radicle: Fix some serialization issues
For some inexplicable reason, deserializing doesn't work unless we use our custom de-serializer for `LocalTime`.
This commit is contained in:
parent
aa13f57e7d
commit
ca557909c2
|
|
@ -129,6 +129,7 @@ impl fmt::Display for State {
|
||||||
/// Repository sync status for our own refs.
|
/// Repository sync status for our own refs.
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, PartialEq, Eq, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
#[serde(tag = "status")]
|
#[serde(tag = "status")]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
pub enum SyncStatus {
|
pub enum SyncStatus {
|
||||||
/// We're in sync.
|
/// We're in sync.
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
|
|
@ -447,7 +448,9 @@ impl Session {
|
||||||
pub struct Seed {
|
pub struct Seed {
|
||||||
pub nid: NodeId,
|
pub nid: NodeId,
|
||||||
pub addrs: Vec<KnownAddress>,
|
pub addrs: Vec<KnownAddress>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
pub state: Option<State>,
|
pub state: Option<State>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
pub sync: Option<SyncStatus>,
|
pub sync: Option<SyncStatus>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1100,9 +1103,26 @@ mod test {
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
"{\"error\":\"entity not found\"}"
|
"{\"error\":\"entity not found\"}"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
json::from_str::<CommandResult<State>>(
|
||||||
|
&serde_json::to_string(&CommandResult::Okay(State::Connected {
|
||||||
|
since: LocalTime::now(),
|
||||||
|
ping: Default::default(),
|
||||||
|
fetching: Default::default(),
|
||||||
|
}))
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
json::from_str::<CommandResult<State>>(
|
||||||
|
r#"{"connected":{"since":1699636852107,"fetching":[]}}"#
|
||||||
|
),
|
||||||
|
Ok(CommandResult::Okay(_))
|
||||||
|
);
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
json::from_str::<CommandResult<Seeds>>(
|
json::from_str::<CommandResult<Seeds>>(
|
||||||
r#"[{"nid":"z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z","addrs":[],"state":{"connected":{"since":1699636852107,"fetching":[]}}}]"#
|
r#"[{"nid":"z6MksmpU5b1dS7oaqF2bHXhQi1DWy2hB7Mh9CuN7y1DN6QSz","addrs":[{"addr":"seed.radicle.xyz:8776","source":"peer","lastSuccess":1699983994234,"lastAttempt":1699983994000,"banned":false}],"state":{"connected":{"since":1699983994,"fetching":[]}}}]"#
|
||||||
),
|
),
|
||||||
Ok(CommandResult::Okay(_))
|
Ok(CommandResult::Okay(_))
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -137,8 +137,10 @@ pub struct KnownAddress {
|
||||||
/// Address of the peer who sent us this address.
|
/// Address of the peer who sent us this address.
|
||||||
pub source: Source,
|
pub source: Source,
|
||||||
/// Last time this address was used to successfully connect to a peer.
|
/// Last time this address was used to successfully connect to a peer.
|
||||||
|
#[serde(with = "crate::serde_ext::localtime::option::time")]
|
||||||
pub last_success: Option<LocalTime>,
|
pub last_success: Option<LocalTime>,
|
||||||
/// Last time this address was tried.
|
/// Last time this address was tried.
|
||||||
|
#[serde(with = "crate::serde_ext::localtime::option::time")]
|
||||||
pub last_attempt: Option<LocalTime>,
|
pub last_attempt: Option<LocalTime>,
|
||||||
/// Whether this address has been banned.
|
/// Whether this address has been banned.
|
||||||
pub banned: bool,
|
pub banned: bool,
|
||||||
|
|
@ -187,6 +189,7 @@ pub struct SyncedAt {
|
||||||
/// Head of `rad/sigrefs`.
|
/// Head of `rad/sigrefs`.
|
||||||
pub oid: git_ext::Oid,
|
pub oid: git_ext::Oid,
|
||||||
/// When these refs were synced.
|
/// When these refs were synced.
|
||||||
|
#[serde(with = "crate::serde_ext::localtime::time")]
|
||||||
pub timestamp: LocalTime,
|
pub timestamp: LocalTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,34 @@ pub mod localtime {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod option {
|
||||||
|
pub mod time {
|
||||||
|
use localtime::LocalTime;
|
||||||
|
use serde::{Deserialize, Deserializer, Serializer};
|
||||||
|
|
||||||
|
pub fn serialize<S>(value: &Option<LocalTime>, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
match value {
|
||||||
|
Some(time) => serializer.serialize_some(&time.as_secs()),
|
||||||
|
None => serializer.serialize_none(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<LocalTime>, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let option = Option::<u64>::deserialize(deserializer)?;
|
||||||
|
match option {
|
||||||
|
Some(seconds) => Ok(Some(LocalTime::from_secs(seconds))),
|
||||||
|
None => Ok(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub mod duration {
|
pub mod duration {
|
||||||
use localtime::LocalDuration;
|
use localtime::LocalDuration;
|
||||||
use serde::{Deserialize, Deserializer, Serializer};
|
use serde::{Deserialize, Deserializer, Serializer};
|
||||||
|
|
@ -81,3 +109,52 @@ pub mod localtime {
|
||||||
pub fn is_default<T: Default + PartialEq>(t: &T) -> bool {
|
pub fn is_default<T: Default + PartialEq>(t: &T) -> bool {
|
||||||
t == &T::default()
|
t == &T::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
use ::localtime::LocalTime;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_localtime() {
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
|
||||||
|
struct Test {
|
||||||
|
time: LocalTime,
|
||||||
|
}
|
||||||
|
let value = Test {
|
||||||
|
time: LocalTime::from_millis(1699636852107),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::from_str::<Test>(r#"{"time":1699636852107}"#).unwrap(),
|
||||||
|
value
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::from_str::<Test>(serde_json::to_string(&value).unwrap().as_str()).unwrap(),
|
||||||
|
value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
// Tests serialization into seconds instead of milliseconds.
|
||||||
|
fn test_localtime_ext() {
|
||||||
|
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
|
||||||
|
struct Test {
|
||||||
|
#[serde(with = "localtime::time")]
|
||||||
|
time: LocalTime,
|
||||||
|
}
|
||||||
|
let value = Test {
|
||||||
|
time: LocalTime::from_secs(1699636852107),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::from_str::<Test>(r#"{"time":1699636852107}"#).unwrap(),
|
||||||
|
value
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::from_str::<Test>(serde_json::to_string(&value).unwrap().as_str()).unwrap(),
|
||||||
|
value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue