1use serde::{de, ser};
2use serde_json::value::RawValue;
3
4#[derive(Debug, Clone)]
6pub struct Object<'a>(&'a RawValue);
7
8impl<'a> Object<'a> {
9 pub fn try_from<'b>(raw: &'b RawValue) -> serde_json::Result<Self>
11 where
12 'b: 'a,
13 {
14 check_raw(raw).map(Self).map_err(ser::Error::custom)
15 }
16
17 pub fn try_into<'b, T>(&'a self) -> serde_json::Result<T>
19 where
20 T: serde::Deserialize<'b>,
21 'a: 'b,
22 {
23 serde_json::from_str(self.0.get())
24 }
25}
26
27impl<'a> PartialEq for Object<'a> {
36 fn eq(&self, other: &Self) -> bool {
37 self.0.get() == other.0.get()
38 }
39}
40
41impl<'a> ser::Serialize for Object<'a> {
42 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
43 where
44 S: serde::Serializer,
45 {
46 self.0.serialize(serializer)
47 }
48}
49
50impl<'de: 'a, 'a> de::Deserialize<'de> for Object<'a> {
51 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
52 where
53 D: serde::Deserializer<'de>,
54 {
55 let raw: &'a RawValue = de::Deserialize::deserialize(deserializer)?;
56 check_raw(raw).map(Self).map_err(de::Error::custom)
57 }
58}
59
60fn check_raw(raw: &RawValue) -> Result<&RawValue, &'static str> {
61 match raw.get().as_bytes().get(0) {
62 Some(b'{') | Some(b'n') => Ok(raw),
63 _ => Err("invalid value: expected null or object"),
64 }
65}
66
67#[cfg(test)]
68mod test {
69 use serde::{Deserialize, Serialize};
70 use serde_json::{from_str, value::to_raw_value, Map, Value};
71
72 use super::*;
73
74 #[derive(Serialize, Deserialize, Debug, PartialEq)]
75 struct Obj<'a> {
76 #[serde(borrow)]
77 ext: Object<'a>,
78 }
79
80 #[derive(Serialize, Deserialize, Debug, PartialEq)]
81 struct Ext<'a> {
82 f1: &'a str,
83 f2: i32,
84 }
85
86 #[test]
87 fn try_from_and_try_into() -> serde_json::Result<()> {
88 let object = Value::Object({
89 let mut m = Map::new();
90 m.insert("f1".into(), Value::String("abc".into()));
91 m.insert("f2".into(), Value::Number(123.into()));
92 m
93 });
94 let raw = to_raw_value(&object)?;
95
96 let obj = Object::try_from(raw.as_ref())?;
97 assert_eq!(
98 obj,
99 Object(serde_json::from_str(r#"{"f1":"abc","f2":123}"#)?)
100 );
101
102 let obj2 = obj.try_into::<Ext>()?;
103 assert_eq!(obj2, Ext { f1: "abc", f2: 123 });
104
105 Ok(())
106 }
107
108 #[test]
109 fn json() -> serde_json::Result<()> {
110 assert!(from_str::<Obj>(r#"{"ext":null}"#).is_ok());
111 assert!(from_str::<Obj>(r#"{"ext":true}"#).is_err());
112 assert!(from_str::<Obj>(r#"{"ext":1}"#).is_err());
113 assert!(from_str::<Obj>(r#"{"ext":"1"}"#).is_err());
114 assert!(from_str::<Obj>(r#"{"ext":[1]}"#).is_err());
115 assert!(from_str::<Obj>(r#"{"ext":{}}"#).is_ok());
116
117 let s1 = r#"{"ext":
118null}"#;
119 let o1 = from_str::<Obj>(s1)?;
120 assert_eq!(
121 o1,
122 Obj {
123 ext: Object::try_from(to_raw_value(&Value::Null)?.as_ref())?,
124 }
125 );
126 assert_eq!(serde_json::to_string(&o1)?, r#"{"ext":null}"#);
127
128 let s2 = r#"{"ext":
129{}
130 }"#;
131 let o2 = serde_json::from_str::<Obj>(s2)?;
132 assert_eq!(
133 o2,
134 Obj {
135 ext: Object::try_from(to_raw_value(&Value::Object(Default::default()))?.as_ref())?,
136 }
137 );
138 assert_eq!(serde_json::to_string(&o2)?, r#"{"ext":{}}"#);
139
140 Ok(())
141 }
142}