Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
radicle: Fix some serialization issues
cloudhead committed 2 years ago
commit ca557909c2bebe2b72bbe9734fe38d49129b5e13
parent aa13f57e7dd96887d6f53f278f2d110076951b69
3 files changed +101 -1
modified radicle/src/node.rs
@@ -129,6 +129,7 @@ impl fmt::Display for State {
/// Repository sync status for our own refs.
#[derive(Debug, PartialEq, Eq, Clone, serde::Serialize, serde::Deserialize)]
#[serde(tag = "status")]
+
#[serde(rename_all = "camelCase")]
pub enum SyncStatus {
    /// We're in sync.
    #[serde(rename_all = "camelCase")]
@@ -447,7 +448,9 @@ impl Session {
pub struct Seed {
    pub nid: NodeId,
    pub addrs: Vec<KnownAddress>,
+
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub state: Option<State>,
+
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub sync: Option<SyncStatus>,
}

@@ -1100,9 +1103,26 @@ mod test {
            .unwrap(),
            "{\"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!(
            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(_))
        );
modified radicle/src/node/address/types.rs
@@ -137,8 +137,10 @@ pub struct KnownAddress {
    /// Address of the peer who sent us this address.
    pub source: Source,
    /// 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>,
    /// Last time this address was tried.
+
    #[serde(with = "crate::serde_ext::localtime::option::time")]
    pub last_attempt: Option<LocalTime>,
    /// Whether this address has been banned.
    pub banned: bool,
@@ -187,6 +189,7 @@ pub struct SyncedAt {
    /// Head of `rad/sigrefs`.
    pub oid: git_ext::Oid,
    /// When these refs were synced.
+
    #[serde(with = "crate::serde_ext::localtime::time")]
    pub timestamp: LocalTime,
}

modified radicle/src/serde_ext.rs
@@ -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 {
        use localtime::LocalDuration;
        use serde::{Deserialize, Deserializer, Serializer};
@@ -81,3 +109,52 @@ pub mod localtime {
pub fn is_default<T: Default + PartialEq>(t: &T) -> bool {
    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
+
        );
+
    }
+
}