sophia_iri/
_serde.rs

1use super::*;
2use serde::{
3    de::{Error, Unexpected},
4    Deserialize, Serialize,
5};
6use std::borrow::Borrow;
7
8impl<'a, T: Borrow<str> + Deserialize<'a>> Deserialize<'a> for Iri<T> {
9    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
10    where
11        D: serde::Deserializer<'a>,
12    {
13        let inner: T = T::deserialize(deserializer)?;
14        Iri::new(inner)
15            .map_err(|err| D::Error::invalid_value(Unexpected::Str(&err.0), &"valid IRI"))
16    }
17}
18
19impl<T: Borrow<str>> Serialize for Iri<T> {
20    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
21    where
22        S: serde::Serializer,
23    {
24        self.as_str().serialize(serializer)
25    }
26}
27
28impl<'a, T: Borrow<str> + Deserialize<'a>> Deserialize<'a> for IriRef<T> {
29    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
30    where
31        D: serde::Deserializer<'a>,
32    {
33        let inner: T = T::deserialize(deserializer)?;
34        IriRef::new(inner)
35            .map_err(|err| D::Error::invalid_value(Unexpected::Str(&err.0), &"valid IRI reference"))
36    }
37}
38
39impl<T: Borrow<str>> Serialize for IriRef<T> {
40    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
41    where
42        S: serde::Serializer,
43    {
44        self.as_str().serialize(serializer)
45    }
46}
47
48#[cfg(test)]
49mod test {
50    use super::*;
51
52    #[derive(Serialize, Deserialize)]
53    struct MyTable {
54        iri: Option<Iri<String>>,
55        iriref: Option<IriRef<String>>,
56    }
57
58    #[derive(Serialize, Deserialize)]
59    struct MyUncheckedTable {
60        iri: Option<String>,
61        iriref: Option<String>,
62    }
63
64    #[test]
65    fn valid_iri() {
66        let data = MyUncheckedTable {
67            iri: Some("http://example.org/".into()),
68            iriref: None,
69        };
70        let toml_str = toml::to_string(&data).unwrap();
71        let data2 = toml::from_str::<MyTable>(&toml_str).unwrap();
72        assert_eq!(data.iri.unwrap(), data2.iri.unwrap().unwrap(),);
73    }
74
75    #[test]
76    fn invalid_iri() {
77        let data = MyUncheckedTable {
78            iri: Some("#foo".into()),
79            iriref: None,
80        };
81        let toml_str = toml::to_string(&data).unwrap();
82        let data2 = toml::from_str::<MyTable>(&toml_str);
83        assert!(data2.is_err());
84    }
85
86    #[test]
87    fn valid_iriref() {
88        let data = MyUncheckedTable {
89            iriref: Some("#foo".into()),
90            iri: None,
91        };
92        let toml_str = toml::to_string(&data).unwrap();
93        let data2 = toml::from_str::<MyTable>(&toml_str).unwrap();
94        assert_eq!(data.iriref.unwrap(), data2.iriref.unwrap().unwrap(),);
95    }
96
97    #[test]
98    fn invalid_iriref() {
99        let data = MyUncheckedTable {
100            iriref: Some("a b".into()),
101            iri: None,
102        };
103        let toml_str = toml::to_string(&data).unwrap();
104        let data2 = toml::from_str::<MyTable>(&toml_str);
105        assert!(data2.is_err());
106    }
107}