junobuild_utils/with/
principal_opt.rs1use 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}