facet_json/raw_json.rs
1//! Raw JSON value that defers parsing.
2//!
3//! [`RawJson`] captures unparsed JSON text, allowing you to delay or skip
4//! deserialization of parts of a JSON document.
5
6use alloc::borrow::Cow;
7use core::fmt;
8use facet::Facet;
9
10/// A raw JSON value that has not been parsed.
11///
12/// This type captures the raw JSON text for a value, deferring parsing until
13/// you're ready (or skipping it entirely if you just need to pass it through).
14///
15/// # Example
16///
17/// ```
18/// use facet::Facet;
19/// use facet_json::RawJson;
20///
21/// #[derive(Facet, Debug)]
22/// struct Response<'a> {
23/// status: u32,
24/// // We don't know what shape `data` has, so defer parsing
25/// data: RawJson<'a>,
26/// }
27///
28/// let json = r#"{"status": 200, "data": {"nested": [1, 2, 3], "complex": true}}"#;
29/// let response: Response = facet_json::from_str(json).unwrap();
30///
31/// assert_eq!(response.status, 200);
32/// assert_eq!(response.data.as_str(), r#"{"nested": [1, 2, 3], "complex": true}"#);
33/// ```
34#[derive(Clone, PartialEq, Eq, Hash, Facet)]
35pub struct RawJson<'a>(pub Cow<'a, str>);
36
37impl<'a> RawJson<'a> {
38 /// Create a new `RawJson` from a string slice.
39 #[inline]
40 pub fn new(s: &'a str) -> Self {
41 RawJson(Cow::Borrowed(s))
42 }
43
44 /// Create a new `RawJson` from an owned string.
45 #[inline]
46 pub fn from_owned(s: alloc::string::String) -> Self {
47 RawJson(Cow::Owned(s))
48 }
49
50 /// Get the raw JSON as a string slice.
51 #[inline]
52 pub fn as_str(&self) -> &str {
53 &self.0
54 }
55
56 /// Convert into an owned `RawJson<'static>`.
57 #[inline]
58 pub fn into_owned(self) -> RawJson<'static> {
59 RawJson(Cow::Owned(self.0.into_owned()))
60 }
61}
62
63impl fmt::Debug for RawJson<'_> {
64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65 f.debug_tuple("RawJson").field(&self.0).finish()
66 }
67}
68
69impl fmt::Display for RawJson<'_> {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 f.write_str(&self.0)
72 }
73}
74
75impl<'a> From<&'a str> for RawJson<'a> {
76 fn from(s: &'a str) -> Self {
77 RawJson::new(s)
78 }
79}
80
81impl<'a> From<Cow<'a, str>> for RawJson<'a> {
82 fn from(s: Cow<'a, str>) -> Self {
83 RawJson(s)
84 }
85}
86
87impl From<alloc::string::String> for RawJson<'static> {
88 fn from(s: alloc::string::String) -> Self {
89 RawJson::from_owned(s)
90 }
91}
92
93impl<'a> AsRef<str> for RawJson<'a> {
94 fn as_ref(&self) -> &str {
95 self.as_str()
96 }
97}