serde_nested_json/
lib.rs

1#![doc = include_str!("../README.md")]
2
3pub mod de;
4pub mod ser;
5
6pub use de::unnest as deserialize;
7pub use ser::nest as serialize;
8
9/// Wraps an instance of T for nested serialization and deserializion.
10/// You will however need to extract and insert the inner value on, so
11/// Its recommended to use the entire module at once instead - see the
12/// main crate docs or README.md for that.
13///
14/// ```rust  
15/// use serde::{Serialize, Deserialize};
16/// use serde_json::{json, from_value, to_string_pretty};
17/// use serde_nested_json::NestedJson;
18///
19/// let as_json = json!({
20///   "nestedJson": "{\"baz\":123}"
21/// });
22///
23/// #[derive(Serialize, Deserialize)]
24/// struct SomeData {
25///   baz: u32
26/// }
27///
28/// #[derive(Serialize, Deserialize)]
29/// #[serde(rename_all = "camelCase")]
30/// struct MyStruct {
31///   nested_json: NestedJson<SomeData>
32/// }
33///
34/// // NestedJson<T> implements From<T>, so you can use t.into()
35/// // as well as NestedJson::from(t)
36/// impl From<SomeData> for MyStruct {
37///   fn from(value: SomeData) -> MyStruct {
38///     MyStruct {
39///       nested_json: value.into()
40///     }
41///   }
42/// }
43///
44/// // There's also an associated `into` fn which returns T
45/// // NestedJson::from is also available, but I havent found
46/// // a way to associate it with with the std::conversion
47/// // traits using stable features
48/// impl From<MyStruct> for SomeData {
49///   fn from(value: MyStruct) -> SomeData {
50///     value.nested_json.into()
51///   }
52/// }
53///
54/// // NestedJson<T> also implements AsRef<T>:
55/// impl AsRef<SomeData> for MyStruct {
56///     fn as_ref(&self) -> &SomeData {
57///         self.nested_json.as_ref()
58///     }
59/// }
60///
61/// let a = SomeData { baz: 32 };
62/// let b: MyStruct = a.into();
63/// let c: SomeData = b.into();
64/// let d: NestedJson<SomeData> = c.into();
65/// let e: SomeData = d.into();
66///
67/// let a = SomeData { baz: 32 };
68/// let b = MyStruct::from(a);
69/// let c = SomeData::from(b);
70/// let d = NestedJson::<SomeData>::from(c);
71/// // Sadly not possible without manual implementation:
72/// // let e = SomeData::from(d);
73///
74/// println!("{}", to_string_pretty(&from_value::<MyStruct>(as_json).unwrap()).unwrap());
75/// ```
76pub struct NestedJson<T>(T);
77
78impl<T> NestedJson<T> {
79    /// Stand-in for `impl<T> From<NestedJson<T>> for T`
80    /// which is not possible to implement without
81    /// non-standard language features.
82    ///
83    /// Makes it possible to use for instance `.map(NestedJson::from)`,
84    /// but sadly not as `std::convert::From`
85    pub fn from(inner: T) -> Self {
86        NestedJson(inner)
87    }
88
89    /// Stand-in for `impl<T> Into<T> for NestedJson<T>`
90    /// which is not possible to implement without
91    /// non-standard language features.
92    ///
93    /// Makes it possible to use for instance `.map(NestedJson::into)`
94    /// but sadly not as `std::convert::Into`
95    pub fn into(self) -> T {
96        self.0
97    }
98}
99
100impl<T> AsRef<T> for NestedJson<T> {
101    fn as_ref(&self) -> &T {
102        &self.0
103    }
104}
105
106impl<T> From<T> for NestedJson<T> {
107    fn from(inner: T) -> Self {
108        Self(inner)
109    }
110}
111
112impl<T: Clone> Clone for NestedJson<T> {
113    fn clone(&self) -> Self {
114        NestedJson(self.0.clone())
115    }
116}
117
118impl<T: std::fmt::Debug> std::fmt::Debug for NestedJson<T> {
119    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
120        f.debug_tuple("NestedJson").field(&self.0).finish()
121    }
122}
123
124impl<T: PartialEq> PartialEq for NestedJson<T> {
125    fn eq(&self, other: &Self) -> bool {
126        self.0 == other.0
127    }
128}
129
130impl<T: Eq> Eq for NestedJson<T> {}
131
132impl<T: PartialOrd> PartialOrd for NestedJson<T> {
133    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
134        self.0.partial_cmp(&other.0)
135    }
136}
137
138impl<T: Ord> Ord for NestedJson<T> {
139    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
140        self.0.cmp(&other.0)
141    }
142}
143
144pub mod vec {
145    pub use super::de::unnest_vec as deserialize;
146    pub use super::ser::nest_iter as serialize;
147}
148
149#[cfg(test)]
150mod tests;