ruma_common/serde/
raw.rs
1use std::{
2 clone::Clone,
3 fmt::{self, Debug},
4 marker::PhantomData,
5 mem,
6};
7
8use serde::{
9 de::{self, Deserialize, DeserializeSeed, Deserializer, IgnoredAny, MapAccess, Visitor},
10 ser::{Serialize, Serializer},
11};
12use serde_json::value::{to_raw_value as to_raw_json_value, RawValue as RawJsonValue};
13
14#[repr(transparent)]
37pub struct Raw<T> {
38 json: Box<RawJsonValue>,
39 _ev: PhantomData<T>,
40}
41
42impl<T> Raw<T> {
43 pub fn new(val: &T) -> serde_json::Result<Self>
52 where
53 T: Serialize,
54 {
55 to_raw_json_value(val).map(Self::from_json)
56 }
57
58 pub fn from_json(json: Box<RawJsonValue>) -> Self {
60 Self { json, _ev: PhantomData }
61 }
62
63 pub fn from_json_string(json: String) -> serde_json::Result<Self> {
71 RawJsonValue::from_string(json).map(Self::from_json)
72 }
73
74 pub fn json(&self) -> &RawJsonValue {
76 &self.json
77 }
78
79 pub fn into_json(self) -> Box<RawJsonValue> {
81 self.json
82 }
83
84 pub fn get_field<'a, U>(&'a self, field_name: &str) -> serde_json::Result<Option<U>>
105 where
106 U: Deserialize<'a>,
107 {
108 struct FieldVisitor<'b>(&'b str);
109
110 impl Visitor<'_> for FieldVisitor<'_> {
111 type Value = bool;
112
113 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
114 write!(formatter, "`{}`", self.0)
115 }
116
117 fn visit_str<E>(self, value: &str) -> Result<bool, E>
118 where
119 E: de::Error,
120 {
121 Ok(value == self.0)
122 }
123 }
124
125 struct Field<'b>(&'b str);
126
127 impl<'de> DeserializeSeed<'de> for Field<'_> {
128 type Value = bool;
129
130 fn deserialize<D>(self, deserializer: D) -> Result<bool, D::Error>
131 where
132 D: Deserializer<'de>,
133 {
134 deserializer.deserialize_identifier(FieldVisitor(self.0))
135 }
136 }
137
138 struct SingleFieldVisitor<'b, T> {
139 field_name: &'b str,
140 _phantom: PhantomData<T>,
141 }
142
143 impl<'b, T> SingleFieldVisitor<'b, T> {
144 fn new(field_name: &'b str) -> Self {
145 Self { field_name, _phantom: PhantomData }
146 }
147 }
148
149 impl<'de, T> Visitor<'de> for SingleFieldVisitor<'_, T>
150 where
151 T: Deserialize<'de>,
152 {
153 type Value = Option<T>;
154
155 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
156 formatter.write_str("a string")
157 }
158
159 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
160 where
161 A: MapAccess<'de>,
162 {
163 let mut res = None;
164 while let Some(is_right_field) = map.next_key_seed(Field(self.field_name))? {
165 if is_right_field {
166 res = Some(map.next_value()?);
167 } else {
168 map.next_value::<IgnoredAny>()?;
169 }
170 }
171
172 Ok(res)
173 }
174 }
175
176 let mut deserializer = serde_json::Deserializer::from_str(self.json().get());
177 deserializer.deserialize_map(SingleFieldVisitor::new(field_name))
178 }
179
180 pub fn deserialize<'a>(&'a self) -> serde_json::Result<T>
182 where
183 T: Deserialize<'a>,
184 {
185 serde_json::from_str(self.json.get())
186 }
187
188 pub fn deserialize_as<'a, U>(&'a self) -> serde_json::Result<U>
190 where
191 U: Deserialize<'a>,
192 {
193 serde_json::from_str(self.json.get())
194 }
195
196 pub fn cast<U>(self) -> Raw<U> {
200 Raw::from_json(self.into_json())
201 }
202
203 pub fn cast_ref<U>(&self) -> &Raw<U> {
207 unsafe { mem::transmute(self) }
208 }
209}
210
211impl<T> Clone for Raw<T> {
212 fn clone(&self) -> Self {
213 Self::from_json(self.json.clone())
214 }
215}
216
217impl<T> Debug for Raw<T> {
218 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
219 use std::any::type_name;
220 f.debug_struct(&format!("Raw::<{}>", type_name::<T>())).field("json", &self.json).finish()
221 }
222}
223
224impl<'de, T> Deserialize<'de> for Raw<T> {
225 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
226 where
227 D: Deserializer<'de>,
228 {
229 Box::<RawJsonValue>::deserialize(deserializer).map(Self::from_json)
230 }
231}
232
233impl<T> Serialize for Raw<T> {
234 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
235 where
236 S: Serializer,
237 {
238 self.json.serialize(serializer)
239 }
240}
241
242#[cfg(test)]
243mod tests {
244 use serde::Deserialize;
245 use serde_json::{from_str as from_json_str, value::RawValue as RawJsonValue};
246
247 use super::Raw;
248
249 #[test]
250 fn get_field() -> serde_json::Result<()> {
251 #[derive(Debug, PartialEq, Deserialize)]
252 struct A<'a> {
253 #[serde(borrow)]
254 b: Vec<&'a str>,
255 }
256
257 const OBJ: &str = r#"{ "a": { "b": [ "c"] }, "z": 5 }"#;
258 let raw: Raw<()> = from_json_str(OBJ)?;
259
260 assert_eq!(raw.get_field::<u8>("z")?, Some(5));
261 assert_eq!(raw.get_field::<&RawJsonValue>("a")?.unwrap().get(), r#"{ "b": [ "c"] }"#);
262 assert_eq!(raw.get_field::<A<'_>>("a")?, Some(A { b: vec!["c"] }));
263
264 assert_eq!(raw.get_field::<u8>("b")?, None);
265 raw.get_field::<u8>("a").unwrap_err();
266
267 Ok(())
268 }
269}