abi_stable/external_types/serde_json.rs
1//! Ffi-safe equivalents of `serde_json` types.
2
3use std::{
4 convert::{TryFrom, TryInto},
5 fmt::{self, Debug, Display},
6};
7
8use serde::{Deserialize, Deserializer, Serialize, Serializer};
9use serde_json::{error::Error as JsonError, value::RawValue};
10
11use crate::std_types::{RStr, RString};
12
13/// An ffi-safe equivalent of `&serde_json::value::RawValue`
14///
15/// # Example
16///
17/// This defines a function that serializes a struct,
18/// and deserializes the json into another one with `RawValueRef` fields.
19///
20/// ```
21/// use abi_stable::{
22/// external_types::RawValueRef,
23/// sabi_extern_fn,
24/// std_types::{RBoxError, RErr, ROk, RResult, RStr, RString},
25/// };
26///
27/// use serde::{Deserialize, Serialize};
28///
29/// use std::collections::HashMap;
30///
31/// const JSON: &'static str = r##"{"hello":"world"}"##;
32///
33/// let value = RawValueRef::try_from_str(JSON).unwrap();
34///
35/// assert_eq!(serde_json::to_string(&value).unwrap().as_str(), JSON);
36///
37/// #[derive(Serialize)]
38/// pub struct Pair {
39/// pub first: Vec<u32>,
40/// pub second: HashMap<RString, RString>,
41/// }
42///
43/// #[derive(Debug, Deserialize)]
44/// pub struct PairDeserialize<'a> {
45/// #[serde(borrow)]
46/// pub first: RawValueRef<'a>,
47///
48/// #[serde(borrow)]
49/// pub second: RawValueRef<'a>,
50/// }
51///
52/// #[sabi_extern_fn]
53/// fn deserialize_data_structure<'de>(
54/// input: RStr<'de>,
55/// ) -> RResult<PairDeserialize<'de>, RBoxError> {
56/// match serde_json::from_str::<PairDeserialize>(input.into()) {
57/// Ok(x) => ROk(x),
58/// Err(x) => RErr(RBoxError::new(x)),
59/// }
60/// }
61///
62/// # fn main(){
63///
64/// let json = serde_json::to_string(&Pair {
65/// first: vec![0, 1, 2],
66/// second: vec![(RString::from("hello"), "world".into())]
67/// .into_iter()
68/// .collect(),
69/// })
70/// .unwrap();
71///
72/// let pair = deserialize_data_structure(json.as_str().into()).unwrap();
73///
74/// assert_eq!(pair.first.get(), "[0,1,2]");
75/// assert_eq!(pair.second.get(), r##"{"hello":"world"}"##);
76///
77/// # }
78///
79/// ```
80#[repr(transparent)]
81#[derive(StableAbi, Copy, Clone)]
82pub struct RawValueRef<'a> {
83 ref_: RStr<'a>,
84}
85
86impl<'a> RawValueRef<'a> {
87 /// Converts a `&str` to a `RawValueRef<'a>` without checking whether it is valid JSON.
88 ///
89 /// # Safety
90 ///
91 /// `input` must be valid JSON and contain no leading or trailing whitespace.
92 ///
93 /// # Example
94 ///
95 /// ```
96 /// use abi_stable::external_types::RawValueRef;
97 ///
98 /// const JSON: &'static str = r##"{"huh":"that is interesting"}"##;
99 ///
100 /// const VALUE: RawValueRef<'_> = unsafe { RawValueRef::from_str_unchecked(JSON) };
101 ///
102 /// assert_eq!(serde_json::to_string(&VALUE).unwrap().as_str(), JSON);
103 ///
104 /// ```
105 pub const unsafe fn from_str_unchecked(input: &'a str) -> RawValueRef<'a> {
106 Self {
107 ref_: RStr::from_str(input),
108 }
109 }
110
111 /// Converts a `RStr<'a>` to a `RawValueRef<'a>` without checking whether it is valid JSON.
112 ///
113 /// # Safety
114 ///
115 /// `input` must be valid JSON and contain no leading or trailing whitespace.
116 ///
117 ///
118 /// # Example
119 ///
120 /// ```
121 /// use abi_stable::{external_types::RawValueRef, std_types::RStr};
122 ///
123 /// const JSON: &'static str = r##"{"huh":"that is interesting"}"##;
124 ///
125 /// let json_rstr = RStr::from(JSON);
126 /// let value = unsafe { RawValueRef::from_rstr_unchecked(json_rstr) };
127 ///
128 /// assert_eq!(serde_json::to_string(&value).unwrap().as_str(), JSON);
129 /// ```
130 ///
131 ///
132 pub const unsafe fn from_rstr_unchecked(input: RStr<'a>) -> RawValueRef<'a> {
133 Self { ref_: input }
134 }
135
136 /// Attempts to convert a `&'a str` into a `RawValueRef<'a>`.
137 ///
138 /// Fails in the same cases as parsing a `&'a RawValue` from a string does.
139 ///
140 /// # Example
141 ///
142 /// ```
143 /// use abi_stable::{external_types::RawValueRef, std_types::RStr};
144 ///
145 /// const JSON: &'static str = r##"{"nope":"oof"}"##;
146 ///
147 /// let raw = RawValueRef::try_from_str(JSON).unwrap();
148 ///
149 /// assert_eq!(raw.get(), JSON);
150 ///
151 /// ```
152 #[inline]
153 pub fn try_from_str(input: &'a str) -> Result<Self, JsonError> {
154 input.try_into()
155 }
156
157 /// Gets the json being serialized,as a `&str`.
158 ///
159 /// # Example
160 ///
161 /// ```
162 /// use abi_stable::external_types::RawValueRef;
163 ///
164 /// const JSON: &'static str = r##"{"huh":1007}"##;
165 ///
166 /// let raw = serde_json::from_str::<RawValueRef<'static>>(JSON).unwrap();
167 ///
168 /// assert_eq!(raw.get(), JSON);
169 ///
170 /// ```
171 #[inline]
172 pub fn get(&self) -> &'a str {
173 self.ref_.as_str()
174 }
175
176 /// Gets the json being serialized,as a `RStr<'a>`.
177 ///
178 /// # Example
179 ///
180 /// ```
181 /// use abi_stable::{external_types::RawValueRef, std_types::RStr};
182 ///
183 /// const JSON: &'static str = r##"{"bugs":"life"}"##;
184 ///
185 /// let raw = serde_json::from_str::<RawValueRef<'static>>(JSON).unwrap();
186 ///
187 /// assert_eq!(raw.get_rstr(), RStr::from(JSON));
188 ///
189 /// ```
190 #[inline]
191 pub const fn get_rstr(&self) -> RStr<'a> {
192 self.ref_
193 }
194}
195
196impl<'a> Debug for RawValueRef<'a> {
197 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
198 Debug::fmt(&self.ref_, f)
199 }
200}
201
202impl<'a> Display for RawValueRef<'a> {
203 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
204 Display::fmt(&self.ref_, f)
205 }
206}
207
208impl<'a> From<&'a RawValue> for RawValueRef<'a> {
209 fn from(v: &'a RawValue) -> Self {
210 Self {
211 ref_: v.get().into(),
212 }
213 }
214}
215
216impl<'a> TryFrom<&'a str> for RawValueRef<'a> {
217 type Error = JsonError;
218 fn try_from(v: &'a str) -> Result<Self, JsonError> {
219 serde_json::from_str::<&'a RawValue>(v).map(Self::from)
220 }
221}
222
223impl<'a> Serialize for RawValueRef<'a> {
224 fn serialize<Z>(&self, serializer: Z) -> Result<Z::Ok, Z::Error>
225 where
226 Z: Serializer,
227 {
228 unsafe { into_ref_rawvalue(self.ref_.as_str()).serialize(serializer) }
229 }
230}
231
232impl<'de: 'a, 'a> Deserialize<'de> for RawValueRef<'a> {
233 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
234 where
235 D: Deserializer<'de>,
236 {
237 <&'a RawValue>::deserialize(deserializer).map(Self::from)
238 }
239}
240
241///////////////////////////////////////////////////////////////////////////////
242
243/// An ffi-safe equivalent of `Box<serde_json::value::RawValue>`
244///
245///
246/// # Example
247///
248/// This defines a function that serializes a struct,
249/// and deserializes the json into another one with `RawValueBox` fields.
250///
251/// ```
252/// use abi_stable::{
253/// external_types::RawValueBox,
254/// sabi_extern_fn,
255/// std_types::{RBoxError, RErr, ROk, RResult, RStr, RString},
256/// };
257///
258/// use serde::{Deserialize, Serialize};
259///
260/// const JSON: &'static str = r##"{"hello":"world"}"##;
261///
262/// let value = RawValueBox::try_from_string(JSON.to_string()).unwrap();
263///
264/// assert_eq!(serde_json::to_string(&value).unwrap().as_str(), JSON);
265///
266/// #[derive(Serialize)]
267/// pub struct Pair {
268/// pub first: u64,
269/// pub second: RString,
270/// }
271///
272/// #[derive(Debug, Deserialize)]
273/// pub struct PairDeserialize {
274/// pub first: RawValueBox,
275/// pub second: RawValueBox,
276/// }
277///
278/// #[sabi_extern_fn]
279/// fn deserialize_data_structure(
280/// input: RStr<'_>,
281/// ) -> RResult<PairDeserialize, RBoxError> {
282/// match serde_json::from_str::<PairDeserialize>(input.into()) {
283/// Ok(x) => ROk(x),
284/// Err(x) => RErr(RBoxError::new(x)),
285/// }
286/// }
287///
288/// # fn main(){
289///
290/// let json = serde_json::to_string(&Pair {
291/// first: 99,
292/// second: "How many apples?".into(),
293/// })
294/// .unwrap();
295///
296/// let pair = deserialize_data_structure(json.as_str().into()).unwrap();
297///
298/// assert_eq!(pair.first.get(), "99");
299/// assert_eq!(pair.second.get(), r##""How many apples?"}"##);
300///
301/// # }
302///
303///
304/// ```
305///
306#[repr(transparent)]
307#[derive(StableAbi, Clone)]
308pub struct RawValueBox {
309 string: RString,
310}
311
312impl RawValueBox {
313 /// Converts a `String` to an `RawValueBox` without checking whether it is valid JSON.
314 ///
315 /// # Safety
316 ///
317 /// `input` must be valid JSON and contain no leading or trailing whitespace.
318 ///
319 ///
320 /// # Example
321 ///
322 /// ```
323 /// use abi_stable::external_types::RawValueBox;
324 ///
325 /// const JSON: &'static str = r##"{"huh":"that is interesting"}"##;
326 ///
327 /// let value = unsafe { RawValueBox::from_string_unchecked(JSON.to_string()) };
328 ///
329 /// assert_eq!(serde_json::to_string(&value).unwrap().as_str(), JSON);
330 /// ```
331 ///
332 #[inline]
333 pub unsafe fn from_string_unchecked(input: String) -> RawValueBox {
334 Self {
335 string: input.into(),
336 }
337 }
338
339 /// Converts an `RString` to an `RawValueBox` without checking whether it is valid JSON.
340 ///
341 /// # Safety
342 ///
343 /// `input` must be valid JSON and contain no leading or trailing whitespace.
344 ///
345 ///
346 /// # Example
347 ///
348 /// ```
349 /// use abi_stable::{external_types::RawValueBox, std_types::RString};
350 ///
351 /// const JSON: &'static str = r##"{"huh":"that is interesting"}"##;
352 ///
353 /// let json_rstring = RString::from(JSON);
354 /// let value = unsafe { RawValueBox::from_rstring_unchecked(json_rstring) };
355 ///
356 /// assert_eq!(serde_json::to_string(&value).unwrap().as_str(), JSON);
357 /// ```
358 ///
359 #[inline]
360 pub const unsafe fn from_rstring_unchecked(input: RString) -> RawValueBox {
361 Self { string: input }
362 }
363
364 /// Attempts to convert a `String` into a `RawValueBox`.
365 ///
366 /// Fails in the same cases as converting a String into a `Box<RawValue>` does.
367 ///
368 /// # Example
369 ///
370 /// ```
371 /// use abi_stable::{external_types::RawValueBox, std_types::RString};
372 ///
373 /// const JSON: &'static str = r##"{"nope":"oof"}"##;
374 ///
375 /// let raw = RawValueBox::try_from_string(JSON.to_string()).unwrap();
376 ///
377 /// assert_eq!(raw.get(), JSON);
378 ///
379 /// ```
380 #[inline]
381 pub fn try_from_string(input: String) -> Result<Self, JsonError> {
382 input.try_into()
383 }
384
385 /// Gets the json being serialized,as a `&str`.
386 ///
387 /// # Example
388 ///
389 /// ```
390 /// use abi_stable::external_types::RawValueBox;
391 ///
392 /// const JSON: &'static str = r##"{"huh":1007}"##;
393 ///
394 /// let raw = serde_json::from_str::<RawValueBox>(JSON).unwrap();
395 ///
396 /// assert_eq!(raw.get(), JSON);
397 ///
398 /// ```
399 #[inline]
400 pub fn get(&self) -> &str {
401 self.string.as_str()
402 }
403
404 /// Gets the json being serialized,as a `RStr<'a>`.
405 ///
406 /// # Example
407 ///
408 /// ```
409 /// use abi_stable::{external_types::RawValueBox, std_types::RStr};
410 ///
411 /// const JSON: &'static str = r##"{"bugs":"life"}"##;
412 ///
413 /// let raw = serde_json::from_str::<RawValueBox>(JSON).unwrap();
414 ///
415 /// assert_eq!(raw.get_rstr(), RStr::from(JSON));
416 ///
417 /// ```
418 #[inline]
419 pub fn get_rstr(&self) -> RStr<'_> {
420 self.get().into()
421 }
422
423 /// Gets a RawValueRef<'_> borrowing from this RawValueBox.
424 ///
425 /// # Example
426 ///
427 /// ```
428 /// use abi_stable::external_types::{RawValueBox, RawValueRef};
429 ///
430 /// const JSON: &'static str = r##"{"bugs":"life"}"##;
431 ///
432 /// let raw = serde_json::from_str::<RawValueBox>(JSON).unwrap();
433 ///
434 /// assert_eq!(raw.get(), RawValueRef::try_from_str(JSON).unwrap().get());
435 ///
436 /// ```
437 #[inline]
438 pub fn as_raw_value_ref(&self) -> RawValueRef<'_> {
439 unsafe { RawValueRef::from_str_unchecked(self.get()) }
440 }
441}
442
443impl Debug for RawValueBox {
444 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
445 Debug::fmt(&self.string, f)
446 }
447}
448
449impl Display for RawValueBox {
450 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
451 Display::fmt(&self.string, f)
452 }
453}
454
455impl From<Box<RawValue>> for RawValueBox {
456 fn from(v: Box<RawValue>) -> Self {
457 let string: String = from_boxed_rawvalue(v).into();
458 Self {
459 string: string.into(),
460 }
461 }
462}
463
464impl TryFrom<String> for RawValueBox {
465 type Error = JsonError;
466 fn try_from(v: String) -> Result<Self, JsonError> {
467 RawValue::from_string(v).map(Self::from)
468 }
469}
470
471impl Serialize for RawValueBox {
472 fn serialize<Z>(&self, serializer: Z) -> Result<Z::Ok, Z::Error>
473 where
474 Z: Serializer,
475 {
476 unsafe { into_ref_rawvalue(&self.string).serialize(serializer) }
477 }
478}
479
480impl<'de> Deserialize<'de> for RawValueBox {
481 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
482 where
483 D: Deserializer<'de>,
484 {
485 <Box<RawValue>>::deserialize(deserializer).map(Self::from)
486 }
487}
488
489///////////////////////////////////////////////////////////////////////////////
490
491fn from_boxed_rawvalue(x: Box<RawValue>) -> Box<str> {
492 // This would become Undefined Behavior if
493 // serde_json somehow changes RawValue to not be a transparent wrapper around `str`
494 unsafe { Box::from_raw(Box::into_raw(x) as *mut str) }
495}
496
497const unsafe fn into_ref_rawvalue(x: &str) -> &RawValue {
498 // This would become Undefined Behavior if
499 // serde_json somehow changes RawValue to not be a transparent wrapper around `str`
500 unsafe { &*(x as *const str as *const RawValue) }
501}