serde_json_pythonic/
raw.rs

1use crate::error::Error;
2use alloc::borrow::ToOwned;
3use alloc::boxed::Box;
4use alloc::string::String;
5use core::fmt::{self, Debug, Display};
6use core::mem;
7use serde::de::value::BorrowedStrDeserializer;
8use serde::de::{
9    self, Deserialize, DeserializeSeed, Deserializer, IntoDeserializer, MapAccess, Unexpected,
10    Visitor,
11};
12use serde::forward_to_deserialize_any;
13use serde::ser::{Serialize, SerializeStruct, Serializer};
14
15/// Reference to a range of bytes encompassing a single valid JSON value in the
16/// input data.
17///
18/// A `RawValue` can be used to defer parsing parts of a payload until later,
19/// or to avoid parsing it at all in the case that part of the payload just
20/// needs to be transferred verbatim into a different output object.
21///
22/// When serializing, a value of this type will retain its original formatting
23/// and will not be minified or pretty-printed.
24///
25/// # Note
26///
27/// `RawValue` is only available if serde\_json is built with the `"raw_value"`
28/// feature.
29///
30/// ```toml
31/// [dependencies]
32/// serde_json_pythonic = { version = "1.0", features = ["raw_value"] }
33/// ```
34///
35/// # Example
36///
37/// ```
38/// use serde::{Deserialize, Serialize};
39/// use serde_json_pythonic::{Result, value::RawValue};
40///
41/// #[derive(Deserialize)]
42/// struct Input<'a> {
43///     code: u32,
44///     #[serde(borrow)]
45///     payload: &'a RawValue,
46/// }
47///
48/// #[derive(Serialize)]
49/// struct Output<'a> {
50///     info: (u32, &'a RawValue),
51/// }
52///
53/// // Efficiently rearrange JSON input containing separate "code" and "payload"
54/// // keys into a single "info" key holding an array of code and payload.
55/// //
56/// // This could be done equivalently using serde_json_pythonic::Value as the type for
57/// // payload, but &RawValue will perform better because it does not require
58/// // memory allocation. The correct range of bytes is borrowed from the input
59/// // data and pasted verbatim into the output.
60/// fn rearrange(input: &str) -> Result<String> {
61///     let input: Input = serde_json_pythonic::from_str(input)?;
62///
63///     let output = Output {
64///         info: (input.code, input.payload),
65///     };
66///
67///     serde_json_pythonic::to_string(&output)
68/// }
69///
70/// fn main() -> Result<()> {
71///     let out = rearrange(r#" {"code": 200, "payload": {}} "#)?;
72///
73///     assert_eq!(out, r#"{"info":[200,{}]}"#);
74///
75///     Ok(())
76/// }
77/// ```
78///
79/// # Ownership
80///
81/// The typical usage of `RawValue` will be in the borrowed form:
82///
83/// ```
84/// # use serde::Deserialize;
85/// # use serde_json_pythonic::value::RawValue;
86/// #
87/// #[derive(Deserialize)]
88/// struct SomeStruct<'a> {
89///     #[serde(borrow)]
90///     raw_value: &'a RawValue,
91/// }
92/// ```
93///
94/// The borrowed form is suitable when deserializing through
95/// [`serde_json_pythonic::from_str`] and [`serde_json_pythonic::from_slice`] which support
96/// borrowing from the input data without memory allocation.
97///
98/// When deserializing through [`serde_json_pythonic::from_reader`] you will need to use
99/// the boxed form of `RawValue` instead. This is almost as efficient but
100/// involves buffering the raw value from the I/O stream into memory.
101///
102/// [`serde_json_pythonic::from_str`]: ../fn.from_str.html
103/// [`serde_json_pythonic::from_slice`]: ../fn.from_slice.html
104/// [`serde_json_pythonic::from_reader`]: ../fn.from_reader.html
105///
106/// ```
107/// # use serde::Deserialize;
108/// # use serde_json_pythonic::value::RawValue;
109/// #
110/// #[derive(Deserialize)]
111/// struct SomeStruct {
112///     raw_value: Box<RawValue>,
113/// }
114/// ```
115#[cfg_attr(not(doc), repr(transparent))]
116#[cfg_attr(docsrs, doc(cfg(feature = "raw_value")))]
117pub struct RawValue {
118    json: str,
119}
120
121impl RawValue {
122    fn from_borrowed(json: &str) -> &Self {
123        unsafe { mem::transmute::<&str, &RawValue>(json) }
124    }
125
126    fn from_owned(json: Box<str>) -> Box<Self> {
127        unsafe { mem::transmute::<Box<str>, Box<RawValue>>(json) }
128    }
129
130    fn into_owned(raw_value: Box<Self>) -> Box<str> {
131        unsafe { mem::transmute::<Box<RawValue>, Box<str>>(raw_value) }
132    }
133}
134
135impl Clone for Box<RawValue> {
136    fn clone(&self) -> Self {
137        (**self).to_owned()
138    }
139}
140
141impl ToOwned for RawValue {
142    type Owned = Box<RawValue>;
143
144    fn to_owned(&self) -> Self::Owned {
145        RawValue::from_owned(self.json.to_owned().into_boxed_str())
146    }
147}
148
149impl Default for Box<RawValue> {
150    fn default() -> Self {
151        RawValue::from_borrowed("null").to_owned()
152    }
153}
154
155impl Debug for RawValue {
156    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
157        formatter
158            .debug_tuple("RawValue")
159            .field(&format_args!("{}", &self.json))
160            .finish()
161    }
162}
163
164impl Display for RawValue {
165    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
166        f.write_str(&self.json)
167    }
168}
169
170impl RawValue {
171    /// Convert an owned `String` of JSON data to an owned `RawValue`.
172    ///
173    /// This function is equivalent to `serde_json_pythonic::from_str::<Box<RawValue>>`
174    /// except that we avoid an allocation and memcpy if both of the following
175    /// are true:
176    ///
177    /// - the input has no leading or trailing whitespace, and
178    /// - the input has capacity equal to its length.
179    pub fn from_string(json: String) -> Result<Box<Self>, Error> {
180        {
181            let borrowed = crate::from_str::<&Self>(&json)?;
182            if borrowed.json.len() < json.len() {
183                return Ok(borrowed.to_owned());
184            }
185        }
186        Ok(Self::from_owned(json.into_boxed_str()))
187    }
188
189    /// Access the JSON text underlying a raw value.
190    ///
191    /// # Example
192    ///
193    /// ```
194    /// use serde::Deserialize;
195    /// use serde_json_pythonic::{Result, value::RawValue};
196    ///
197    /// #[derive(Deserialize)]
198    /// struct Response<'a> {
199    ///     code: u32,
200    ///     #[serde(borrow)]
201    ///     payload: &'a RawValue,
202    /// }
203    ///
204    /// fn process(input: &str) -> Result<()> {
205    ///     let response: Response = serde_json_pythonic::from_str(input)?;
206    ///
207    ///     let payload = response.payload.get();
208    ///     if payload.starts_with('{') {
209    ///         // handle a payload which is a JSON map
210    ///     } else {
211    ///         // handle any other type
212    ///     }
213    ///
214    ///     Ok(())
215    /// }
216    ///
217    /// fn main() -> Result<()> {
218    ///     process(r#" {"code": 200, "payload": {}} "#)?;
219    ///     Ok(())
220    /// }
221    /// ```
222    pub fn get(&self) -> &str {
223        &self.json
224    }
225}
226
227impl From<Box<RawValue>> for Box<str> {
228    fn from(raw_value: Box<RawValue>) -> Self {
229        RawValue::into_owned(raw_value)
230    }
231}
232
233/// Convert a `T` into a boxed `RawValue`.
234///
235/// # Example
236///
237/// ```
238/// // Upstream crate
239/// # #[derive(Serialize)]
240/// pub struct Thing {
241///     foo: String,
242///     bar: Option<String>,
243///     extra_data: Box<RawValue>,
244/// }
245///
246/// // Local crate
247/// use serde::Serialize;
248/// use serde_json_pythonic::value::{to_raw_value, RawValue};
249///
250/// #[derive(Serialize)]
251/// struct MyExtraData {
252///     a: u32,
253///     b: u32,
254/// }
255///
256/// let my_thing = Thing {
257///     foo: "FooVal".into(),
258///     bar: None,
259///     extra_data: to_raw_value(&MyExtraData { a: 1, b: 2 }).unwrap(),
260/// };
261/// # assert_eq!(
262/// #     serde_json_pythonic::to_value(my_thing).unwrap(),
263/// #     serde_json_pythonic::json!({
264/// #         "foo": "FooVal",
265/// #         "bar": null,
266/// #         "extra_data": { "a": 1, "b": 2 }
267/// #     })
268/// # );
269/// ```
270///
271/// # Errors
272///
273/// This conversion can fail if `T`'s implementation of `Serialize` decides to
274/// fail, or if `T` contains a map with non-string keys.
275///
276/// ```
277/// use std::collections::BTreeMap;
278///
279/// // The keys in this map are vectors, not strings.
280/// let mut map = BTreeMap::new();
281/// map.insert(vec![32, 64], "x86");
282///
283/// println!("{}", serde_json_pythonic::value::to_raw_value(&map).unwrap_err());
284/// ```
285#[cfg_attr(docsrs, doc(cfg(feature = "raw_value")))]
286pub fn to_raw_value<T>(value: &T) -> Result<Box<RawValue>, Error>
287where
288    T: ?Sized + Serialize,
289{
290    let json_string = crate::to_string(value)?;
291    Ok(RawValue::from_owned(json_string.into_boxed_str()))
292}
293
294pub const TOKEN: &str = "$serde_json::private::RawValue";
295
296impl Serialize for RawValue {
297    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
298    where
299        S: Serializer,
300    {
301        let mut s = serializer.serialize_struct(TOKEN, 1)?;
302        s.serialize_field(TOKEN, &self.json)?;
303        s.end()
304    }
305}
306
307impl<'de: 'a, 'a> Deserialize<'de> for &'a RawValue {
308    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
309    where
310        D: Deserializer<'de>,
311    {
312        struct ReferenceVisitor;
313
314        impl<'de> Visitor<'de> for ReferenceVisitor {
315            type Value = &'de RawValue;
316
317            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
318                write!(formatter, "any valid JSON value")
319            }
320
321            fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
322            where
323                V: MapAccess<'de>,
324            {
325                let value = visitor.next_key::<RawKey>()?;
326                if value.is_none() {
327                    return Err(de::Error::invalid_type(Unexpected::Map, &self));
328                }
329                visitor.next_value_seed(ReferenceFromString)
330            }
331        }
332
333        deserializer.deserialize_newtype_struct(TOKEN, ReferenceVisitor)
334    }
335}
336
337impl<'de> Deserialize<'de> for Box<RawValue> {
338    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
339    where
340        D: Deserializer<'de>,
341    {
342        struct BoxedVisitor;
343
344        impl<'de> Visitor<'de> for BoxedVisitor {
345            type Value = Box<RawValue>;
346
347            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
348                write!(formatter, "any valid JSON value")
349            }
350
351            fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
352            where
353                V: MapAccess<'de>,
354            {
355                let value = visitor.next_key::<RawKey>()?;
356                if value.is_none() {
357                    return Err(de::Error::invalid_type(Unexpected::Map, &self));
358                }
359                visitor.next_value_seed(BoxedFromString)
360            }
361        }
362
363        deserializer.deserialize_newtype_struct(TOKEN, BoxedVisitor)
364    }
365}
366
367struct RawKey;
368
369impl<'de> Deserialize<'de> for RawKey {
370    fn deserialize<D>(deserializer: D) -> Result<RawKey, D::Error>
371    where
372        D: Deserializer<'de>,
373    {
374        struct FieldVisitor;
375
376        impl<'de> Visitor<'de> for FieldVisitor {
377            type Value = ();
378
379            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
380                formatter.write_str("raw value")
381            }
382
383            fn visit_str<E>(self, s: &str) -> Result<(), E>
384            where
385                E: de::Error,
386            {
387                if s == TOKEN {
388                    Ok(())
389                } else {
390                    Err(de::Error::custom("unexpected raw value"))
391                }
392            }
393        }
394
395        deserializer.deserialize_identifier(FieldVisitor)?;
396        Ok(RawKey)
397    }
398}
399
400pub struct ReferenceFromString;
401
402impl<'de> DeserializeSeed<'de> for ReferenceFromString {
403    type Value = &'de RawValue;
404
405    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
406    where
407        D: Deserializer<'de>,
408    {
409        deserializer.deserialize_str(self)
410    }
411}
412
413impl<'de> Visitor<'de> for ReferenceFromString {
414    type Value = &'de RawValue;
415
416    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
417        formatter.write_str("raw value")
418    }
419
420    fn visit_borrowed_str<E>(self, s: &'de str) -> Result<Self::Value, E>
421    where
422        E: de::Error,
423    {
424        Ok(RawValue::from_borrowed(s))
425    }
426}
427
428pub struct BoxedFromString;
429
430impl<'de> DeserializeSeed<'de> for BoxedFromString {
431    type Value = Box<RawValue>;
432
433    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
434    where
435        D: Deserializer<'de>,
436    {
437        deserializer.deserialize_str(self)
438    }
439}
440
441impl<'de> Visitor<'de> for BoxedFromString {
442    type Value = Box<RawValue>;
443
444    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
445        formatter.write_str("raw value")
446    }
447
448    fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
449    where
450        E: de::Error,
451    {
452        Ok(RawValue::from_owned(s.to_owned().into_boxed_str()))
453    }
454
455    #[cfg(any(feature = "std", feature = "alloc"))]
456    fn visit_string<E>(self, s: String) -> Result<Self::Value, E>
457    where
458        E: de::Error,
459    {
460        Ok(RawValue::from_owned(s.into_boxed_str()))
461    }
462}
463
464struct RawKeyDeserializer;
465
466impl<'de> Deserializer<'de> for RawKeyDeserializer {
467    type Error = Error;
468
469    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
470    where
471        V: de::Visitor<'de>,
472    {
473        visitor.visit_borrowed_str(TOKEN)
474    }
475
476    forward_to_deserialize_any! {
477        bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq
478        bytes byte_buf map struct option unit newtype_struct ignored_any
479        unit_struct tuple_struct tuple enum identifier
480    }
481}
482
483pub struct OwnedRawDeserializer {
484    pub raw_value: Option<String>,
485}
486
487impl<'de> MapAccess<'de> for OwnedRawDeserializer {
488    type Error = Error;
489
490    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
491    where
492        K: de::DeserializeSeed<'de>,
493    {
494        if self.raw_value.is_none() {
495            return Ok(None);
496        }
497        seed.deserialize(RawKeyDeserializer).map(Some)
498    }
499
500    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
501    where
502        V: de::DeserializeSeed<'de>,
503    {
504        seed.deserialize(self.raw_value.take().unwrap().into_deserializer())
505    }
506}
507
508pub struct BorrowedRawDeserializer<'de> {
509    pub raw_value: Option<&'de str>,
510}
511
512impl<'de> MapAccess<'de> for BorrowedRawDeserializer<'de> {
513    type Error = Error;
514
515    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
516    where
517        K: de::DeserializeSeed<'de>,
518    {
519        if self.raw_value.is_none() {
520            return Ok(None);
521        }
522        seed.deserialize(RawKeyDeserializer).map(Some)
523    }
524
525    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
526    where
527        V: de::DeserializeSeed<'de>,
528    {
529        seed.deserialize(BorrowedStrDeserializer::new(self.raw_value.take().unwrap()))
530    }
531}