feat: init
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
use serde::ser::{Serialize, SerializeMap, Serializer};
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::error::AppError;
|
||||
|
||||
use super::interface::SessionState;
|
||||
|
||||
const SESSION_STATE_FORMAT_VERSION: u8 = 1;
|
||||
|
||||
struct StoredSessionStateRef<'a> {
|
||||
state: &'a SessionState,
|
||||
}
|
||||
|
||||
impl Serialize for StoredSessionStateRef<'_> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut map = serializer.serialize_map(Some(2))?;
|
||||
map.serialize_entry("v", &SESSION_STATE_FORMAT_VERSION)?;
|
||||
map.serialize_entry("state", self.state)?;
|
||||
map.end()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn serialize_session_state(session_state: &SessionState) -> Result<String, AppError> {
|
||||
let stored = StoredSessionStateRef {
|
||||
state: session_state,
|
||||
};
|
||||
serde_json::to_string(&stored).map_err(AppError::Json)
|
||||
}
|
||||
|
||||
pub fn deserialize_session_state(value: &str) -> Result<SessionState, AppError> {
|
||||
let value: Value = serde_json::from_str(value)?;
|
||||
let Value::Object(mut obj) = value else {
|
||||
return Err(AppError::Config("invalid session state format".into()));
|
||||
};
|
||||
|
||||
if let Some(Value::Object(_)) = obj.get("state")
|
||||
&& let Some(Value::Number(v)) = obj.get("v")
|
||||
{
|
||||
let version = v
|
||||
.as_u64()
|
||||
.and_then(|n| u8::try_from(n).ok())
|
||||
.ok_or_else(|| AppError::Config("invalid session state format version".into()))?;
|
||||
|
||||
if version != SESSION_STATE_FORMAT_VERSION {
|
||||
return Err(AppError::Config(format!(
|
||||
"unsupported session state format version: {version}"
|
||||
)));
|
||||
}
|
||||
|
||||
let Some(Value::Object(state)) = obj.remove("state") else {
|
||||
return Err(AppError::Config("missing session state".into()));
|
||||
};
|
||||
return Ok(state);
|
||||
}
|
||||
|
||||
Ok(obj)
|
||||
}
|
||||
Reference in New Issue
Block a user