Skip to main content

junobuild_utils/with/
principal_opt.rs

1use crate::serializers::types::JsonDataPrincipal;
2use candid::Principal;
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4
5pub fn serialize<S>(principal: &Option<Principal>, s: S) -> Result<S::Ok, S::Error>
6where
7    S: Serializer,
8{
9    match principal {
10        Some(p) => JsonDataPrincipal { value: *p }.serialize(s),
11        None => s.serialize_none(),
12    }
13}
14
15pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Principal>, D::Error>
16where
17    D: Deserializer<'de>,
18{
19    Option::<JsonDataPrincipal>::deserialize(deserializer).map(|opt| opt.map(|d| d.value))
20}
21
22#[cfg(test)]
23mod tests {
24    use candid::Principal;
25    use serde::{Deserialize, Serialize};
26    use serde_json;
27
28    #[derive(Serialize, Deserialize, PartialEq, Debug)]
29    struct TestStruct {
30        #[serde(with = "super")]
31        value: Option<Principal>,
32    }
33
34    fn p(txt: &str) -> Principal {
35        Principal::from_text(txt).expect("principal text should parse")
36    }
37
38    #[test]
39    fn serialize_some() {
40        let s = TestStruct {
41            value: Some(p("aaaaa-aa")),
42        };
43        let json = serde_json::to_string(&s).expect("serialize");
44        assert_eq!(json, r#"{"value":{"__principal__":"aaaaa-aa"}}"#);
45    }
46
47    #[test]
48    fn serialize_none() {
49        let s = TestStruct { value: None };
50        let json = serde_json::to_string(&s).expect("serialize");
51        assert_eq!(json, r#"{"value":null}"#);
52    }
53
54    #[test]
55    fn deserialize_some() {
56        let json = r#"{"value":{"__principal__":"aaaaa-aa"}}"#;
57        let s: TestStruct = serde_json::from_str(json).expect("deserialize");
58        assert_eq!(s.value, Some(p("aaaaa-aa")));
59    }
60
61    #[test]
62    fn deserialize_none() {
63        let json = r#"{"value":null}"#;
64        let s: TestStruct = serde_json::from_str(json).expect("deserialize");
65        assert_eq!(s.value, None);
66    }
67
68    #[test]
69    fn round_trip_some() {
70        let original = TestStruct {
71            value: Some(p("ryjl3-tyaaa-aaaaa-aaaba-cai")),
72        };
73        let json = serde_json::to_string(&original).unwrap();
74        let decoded: TestStruct = serde_json::from_str(&json).unwrap();
75        assert_eq!(decoded.value, original.value);
76    }
77
78    #[test]
79    fn round_trip_none() {
80        let original = TestStruct { value: None };
81        let json = serde_json::to_string(&original).unwrap();
82        let decoded: TestStruct = serde_json::from_str(&json).unwrap();
83        assert_eq!(decoded.value, original.value);
84    }
85}