openapi_context/
nullable_format.rs

1// These functions are only used if the API uses Nullable properties, so allow them to be
2// dead code.
3#![allow(dead_code)]
4#[cfg(feature = "serdejson")]
5use serde::de::Error as SerdeError;
6#[cfg(feature = "serdejson")]
7use serde::de::{Deserialize, DeserializeOwned, Deserializer};
8#[cfg(feature = "serdejson")]
9use serde::ser::{Serialize, Serializer};
10use std::clone::Clone;
11
12use std::mem;
13
14/// The Nullable type. Represents a value which may be specified as null on an API.
15/// Note that this is distinct from a value that is optional and not present!
16///
17/// Nullable implements many of the same methods as the Option type (map, unwrap, etc).
18#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
19pub enum Nullable<T> {
20    /// Null value
21    Null,
22    /// Value is present
23    Present(T),
24}
25
26impl<T> Nullable<T> {
27    /////////////////////////////////////////////////////////////////////////
28    // Querying the contained values
29    /////////////////////////////////////////////////////////////////////////
30
31    /// Returns `true` if the Nullable is a `Present` value.
32    ///
33    /// # Examples
34    ///
35    /// ```
36    /// # use ::swagger::Nullable;
37    ///
38    /// let x: Nullable<u32> = Nullable::Present(2);
39    /// assert_eq!(x.is_present(), true);
40    ///
41    /// let x: Nullable<u32> = Nullable::Null;
42    /// assert_eq!(x.is_present(), false);
43    /// ```
44    #[inline]
45    pub fn is_present(&self) -> bool {
46        match *self {
47            Nullable::Present(_) => true,
48            Nullable::Null => false,
49        }
50    }
51
52    /// Returns `true` if the Nullable is a `Null` value.
53    ///
54    /// # Examples
55    ///
56    /// ```
57    /// # use ::swagger::Nullable;
58    ///
59    /// let x: Nullable<u32> = Nullable::Present(2);
60    /// assert_eq!(x.is_null(), false);
61    ///
62    /// let x: Nullable<u32> = Nullable::Null;
63    /// assert_eq!(x.is_null(), true);
64    /// ```
65    #[inline]
66    pub fn is_null(&self) -> bool {
67        !self.is_present()
68    }
69
70    /////////////////////////////////////////////////////////////////////////
71    // Adapter for working with references
72    /////////////////////////////////////////////////////////////////////////
73
74    /// Converts from `Nullable<T>` to `Nullable<&T>`.
75    ///
76    /// # Examples
77    ///
78    /// Convert an `Nullable<`[`String`]`>` into a `Nullable<`[`usize`]`>`, preserving the original.
79    /// The [`map`] method takes the `self` argument by value, consuming the original,
80    /// so this technique uses `as_ref` to first take a `Nullable` to a reference
81    /// to the value inside the original.
82    ///
83    /// [`map`]: enum.Nullable.html#method.map
84    /// [`String`]: ../../std/string/struct.String.html
85    /// [`usize`]: ../../std/primitive.usize.html
86    ///
87    /// ```
88    /// # use ::swagger::Nullable;
89    ///
90    /// let num_as_str: Nullable<String> = Nullable::Present("10".to_string());
91    /// // First, cast `Nullable<String>` to `Nullable<&String>` with `as_ref`,
92    /// // then consume *that* with `map`, leaving `num_as_str` on the stack.
93    /// let num_as_int: Nullable<usize> = num_as_str.as_ref().map(|n| n.len());
94    /// println!("still can print num_as_str: {:?}", num_as_str);
95    /// ```
96    #[inline]
97    pub fn as_ref(&self) -> Nullable<&T> {
98        match *self {
99            Nullable::Present(ref x) => Nullable::Present(x),
100            Nullable::Null => Nullable::Null,
101        }
102    }
103
104    /// Converts from `Nullable<T>` to `Nullable<&mut T>`.
105    ///
106    /// # Examples
107    ///
108    /// ```
109    /// # use ::swagger::Nullable;
110    ///
111    /// let mut x = Nullable::Present(2);
112    /// match x.as_mut() {
113    ///     Nullable::Present(v) => *v = 42,
114    ///     Nullable::Null => {},
115    /// }
116    /// assert_eq!(x, Nullable::Present(42));
117    /// ```
118    #[inline]
119    pub fn as_mut(&mut self) -> Nullable<&mut T> {
120        match *self {
121            Nullable::Present(ref mut x) => Nullable::Present(x),
122            Nullable::Null => Nullable::Null,
123        }
124    }
125
126    /////////////////////////////////////////////////////////////////////////
127    // Getting to contained values
128    /////////////////////////////////////////////////////////////////////////
129
130    /// Unwraps a Nullable, yielding the content of a `Nullable::Present`.
131    ///
132    /// # Panics
133    ///
134    /// Panics if the value is a [`Nullable::Null`] with a custom panic message provided by
135    /// `msg`.
136    ///
137    /// [`Nullable::Null`]: #variant.Null
138    ///
139    /// # Examples
140    ///
141    /// ```
142    /// # use ::swagger::Nullable;
143    ///
144    /// let x = Nullable::Present("value");
145    /// assert_eq!(x.expect("the world is ending"), "value");
146    /// ```
147    ///
148    /// ```{.should_panic}
149    /// # use ::swagger::Nullable;
150    ///
151    /// let x: Nullable<&str> = Nullable::Null;
152    /// x.expect("the world is ending"); // panics with `the world is ending`
153    /// ```
154    #[inline]
155    pub fn expect(self, msg: &str) -> T {
156        match self {
157            Nullable::Present(val) => val,
158            Nullable::Null => expect_failed(msg),
159        }
160    }
161
162    /// Moves the value `v` out of the `Nullable<T>` if it is `Nullable::Present(v)`.
163    ///
164    /// In general, because this function may panic, its use is discouraged.
165    /// Instead, prefer to use pattern matching and handle the `Nullable::Null`
166    /// case explicitly.
167    ///
168    /// # Panics
169    ///
170    /// Panics if the self value equals [`Nullable::Null`].
171    ///
172    /// [`Nullable::Null`]: #variant.Null
173    ///
174    /// # Examples
175    ///
176    /// ```
177    /// # use ::swagger::Nullable;
178    ///
179    /// let x = Nullable::Present("air");
180    /// assert_eq!(x.unwrap(), "air");
181    /// ```
182    ///
183    /// ```{.should_panic}
184    /// # use ::swagger::Nullable;
185    ///
186    /// let x: Nullable<&str> = Nullable::Null;
187    /// assert_eq!(x.unwrap(), "air"); // fails
188    /// ```
189    #[inline]
190    pub fn unwrap(self) -> T {
191        match self {
192            Nullable::Present(val) => val,
193            Nullable::Null => panic!("called `Nullable::unwrap()` on a `Nullable::Null` value"),
194        }
195    }
196
197    /// Returns the contained value or a default.
198    ///
199    /// # Examples
200    ///
201    /// ```
202    /// # use ::swagger::Nullable;
203    ///
204    /// assert_eq!(Nullable::Present("car").unwrap_or("bike"), "car");
205    /// assert_eq!(Nullable::Null.unwrap_or("bike"), "bike");
206    /// ```
207    #[inline]
208    pub fn unwrap_or(self, def: T) -> T {
209        match self {
210            Nullable::Present(x) => x,
211            Nullable::Null => def,
212        }
213    }
214
215    /// Returns the contained value or computes it from a closure.
216    ///
217    /// # Examples
218    ///
219    /// ```
220    /// # use ::swagger::Nullable;
221    ///
222    /// let k = 10;
223    /// assert_eq!(Nullable::Present(4).unwrap_or_else(|| 2 * k), 4);
224    /// assert_eq!(Nullable::Null.unwrap_or_else(|| 2 * k), 20);
225    /// ```
226    #[inline]
227    pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
228        match self {
229            Nullable::Present(x) => x,
230            Nullable::Null => f(),
231        }
232    }
233
234    /////////////////////////////////////////////////////////////////////////
235    // Transforming contained values
236    /////////////////////////////////////////////////////////////////////////
237
238    /// Maps a `Nullable<T>` to `Nullable<U>` by applying a function to a contained value.
239    ///
240    /// # Examples
241    ///
242    /// Convert a `Nullable<`[`String`]`>` into a `Nullable<`[`usize`]`>`, consuming the original:
243    ///
244    /// [`String`]: ../../std/string/struct.String.html
245    /// [`usize`]: ../../std/primitive.usize.html
246    ///
247    /// ```
248    /// # use ::swagger::Nullable;
249    ///
250    /// let maybe_some_string = Nullable::Present(String::from("Hello, World!"));
251    /// // `Nullable::map` takes self *by value*, consuming `maybe_some_string`
252    /// let maybe_some_len = maybe_some_string.map(|s| s.len());
253    ///
254    /// assert_eq!(maybe_some_len, Nullable::Present(13));
255    /// ```
256    #[inline]
257    pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Nullable<U> {
258        match self {
259            Nullable::Present(x) => Nullable::Present(f(x)),
260            Nullable::Null => Nullable::Null,
261        }
262    }
263
264    /// Applies a function to the contained value (if any),
265    /// or returns a `default` (if not).
266    ///
267    /// # Examples
268    ///
269    /// ```
270    /// # use ::swagger::Nullable;
271    ///
272    /// let x = Nullable::Present("foo");
273    /// assert_eq!(x.map_or(42, |v| v.len()), 3);
274    ///
275    /// let x: Nullable<&str> = Nullable::Null;
276    /// assert_eq!(x.map_or(42, |v| v.len()), 42);
277    /// ```
278    #[inline]
279    pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
280        match self {
281            Nullable::Present(t) => f(t),
282            Nullable::Null => default,
283        }
284    }
285
286    /// Applies a function to the contained value (if any),
287    /// or computes a `default` (if not).
288    ///
289    /// # Examples
290    ///
291    /// ```
292    /// # use ::swagger::Nullable;
293    ///
294    /// let k = 21;
295    ///
296    /// let x = Nullable::Present("foo");
297    /// assert_eq!(x.map_or_else(|| 2 * k, |v| v.len()), 3);
298    ///
299    /// let x: Nullable<&str> = Nullable::Null;
300    /// assert_eq!(x.map_or_else(|| 2 * k, |v| v.len()), 42);
301    /// ```
302    #[inline]
303    pub fn map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
304        match self {
305            Nullable::Present(t) => f(t),
306            Nullable::Null => default(),
307        }
308    }
309
310    /// Transforms the `Nullable<T>` into a [`Result<T, E>`], mapping `Nullable::Present(v)` to
311    /// [`Ok(v)`] and `Nullable::Null` to [`Err(err)`][Err].
312    ///
313    /// [`Result<T, E>`]: ../../std/result/enum.Result.html
314    /// [`Ok(v)`]: ../../std/result/enum.Result.html#variant.Ok
315    /// [Err]: ../../std/result/enum.Result.html#variant.Err
316    ///
317    /// # Examples
318    ///
319    /// ```
320    /// # use ::swagger::Nullable;
321    ///
322    /// let x = Nullable::Present("foo");
323    /// assert_eq!(x.ok_or(0), Ok("foo"));
324    ///
325    /// let x: Nullable<&str> = Nullable::Null;
326    /// assert_eq!(x.ok_or(0), Err(0));
327    /// ```
328    #[inline]
329    pub fn ok_or<E>(self, err: E) -> Result<T, E> {
330        match self {
331            Nullable::Present(v) => Ok(v),
332            Nullable::Null => Err(err),
333        }
334    }
335
336    /// Transforms the `Nullable<T>` into a [`Result<T, E>`], mapping `Nullable::Present(v)` to
337    /// [`Ok(v)`] and `Nullable::Null` to [`Err(err())`][Err].
338    ///
339    /// [`Result<T, E>`]: ../../std/result/enum.Result.html
340    /// [`Ok(v)`]: ../../std/result/enum.Result.html#variant.Ok
341    /// [Err]: ../../std/result/enum.Result.html#variant.Err
342    ///
343    /// # Examples
344    ///
345    /// ```
346    /// # use ::swagger::Nullable;
347    ///
348    /// let x = Nullable::Present("foo");
349    /// assert_eq!(x.ok_or_else(|| 0), Ok("foo"));
350    ///
351    /// let x: Nullable<&str> = Nullable::Null;
352    /// assert_eq!(x.ok_or_else(|| 0), Err(0));
353    /// ```
354    #[inline]
355    pub fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E> {
356        match self {
357            Nullable::Present(v) => Ok(v),
358            Nullable::Null => Err(err()),
359        }
360    }
361
362    /////////////////////////////////////////////////////////////////////////
363    // Boolean operations on the values, eager and lazy
364    /////////////////////////////////////////////////////////////////////////
365
366    /// Returns `Nullable::Null` if the Nullable is `Nullable::Null`, otherwise returns `optb`.
367    ///
368    /// # Examples
369    ///
370    /// ```
371    /// # use ::swagger::Nullable;
372    ///
373    /// let x = Nullable::Present(2);
374    /// let y: Nullable<&str> = Nullable::Null;
375    /// assert_eq!(x.and(y), Nullable::Null);
376    ///
377    /// let x: Nullable<u32> = Nullable::Null;
378    /// let y = Nullable::Present("foo");
379    /// assert_eq!(x.and(y), Nullable::Null);
380    ///
381    /// let x = Nullable::Present(2);
382    /// let y = Nullable::Present("foo");
383    /// assert_eq!(x.and(y), Nullable::Present("foo"));
384    ///
385    /// let x: Nullable<u32> = Nullable::Null;
386    /// let y: Nullable<&str> = Nullable::Null;
387    /// assert_eq!(x.and(y), Nullable::Null);
388    /// ```
389    #[inline]
390    pub fn and<U>(self, optb: Nullable<U>) -> Nullable<U> {
391        match self {
392            Nullable::Present(_) => optb,
393            Nullable::Null => Nullable::Null,
394        }
395    }
396
397    /// Returns `Nullable::Null` if the Nullable is `Nullable::Null`, otherwise calls `f` with the
398    /// wrapped value and returns the result.
399    ///
400    /// Some languages call this operation flatmap.
401    ///
402    /// # Examples
403    ///
404    /// ```
405    /// # use ::swagger::Nullable;
406    ///
407    /// fn sq(x: u32) -> Nullable<u32> { Nullable::Present(x * x) }
408    /// fn nope(_: u32) -> Nullable<u32> { Nullable::Null }
409    ///
410    /// assert_eq!(Nullable::Present(2).and_then(sq).and_then(sq), Nullable::Present(16));
411    /// assert_eq!(Nullable::Present(2).and_then(sq).and_then(nope), Nullable::Null);
412    /// assert_eq!(Nullable::Present(2).and_then(nope).and_then(sq), Nullable::Null);
413    /// assert_eq!(Nullable::Null.and_then(sq).and_then(sq), Nullable::Null);
414    /// ```
415    #[inline]
416    pub fn and_then<U, F: FnOnce(T) -> Nullable<U>>(self, f: F) -> Nullable<U> {
417        match self {
418            Nullable::Present(x) => f(x),
419            Nullable::Null => Nullable::Null,
420        }
421    }
422
423    /// Returns the Nullable if it contains a value, otherwise returns `optb`.
424    ///
425    /// # Examples
426    ///
427    /// ```
428    /// # use ::swagger::Nullable;
429    ///
430    /// let x = Nullable::Present(2);
431    /// let y = Nullable::Null;
432    /// assert_eq!(x.or(y), Nullable::Present(2));
433    ///
434    /// let x = Nullable::Null;
435    /// let y = Nullable::Present(100);
436    /// assert_eq!(x.or(y), Nullable::Present(100));
437    ///
438    /// let x = Nullable::Present(2);
439    /// let y = Nullable::Present(100);
440    /// assert_eq!(x.or(y), Nullable::Present(2));
441    ///
442    /// let x: Nullable<u32> = Nullable::Null;
443    /// let y = Nullable::Null;
444    /// assert_eq!(x.or(y), Nullable::Null);
445    /// ```
446    #[inline]
447    pub fn or(self, optb: Nullable<T>) -> Nullable<T> {
448        match self {
449            Nullable::Present(_) => self,
450            Nullable::Null => optb,
451        }
452    }
453
454    /// Returns the Nullable if it contains a value, otherwise calls `f` and
455    /// returns the result.
456    ///
457    /// # Examples
458    ///
459    /// ```
460    /// # use ::swagger::Nullable;
461    ///
462    /// fn nobody() -> Nullable<&'static str> { Nullable::Null }
463    /// fn vikings() -> Nullable<&'static str> { Nullable::Present("vikings") }
464    ///
465    /// assert_eq!(Nullable::Present("barbarians").or_else(vikings),
466    ///            Nullable::Present("barbarians"));
467    /// assert_eq!(Nullable::Null.or_else(vikings), Nullable::Present("vikings"));
468    /// assert_eq!(Nullable::Null.or_else(nobody), Nullable::Null);
469    /// ```
470    #[inline]
471    pub fn or_else<F: FnOnce() -> Nullable<T>>(self, f: F) -> Nullable<T> {
472        match self {
473            Nullable::Present(_) => self,
474            Nullable::Null => f(),
475        }
476    }
477
478    /////////////////////////////////////////////////////////////////////////
479    // Misc
480    /////////////////////////////////////////////////////////////////////////
481
482    /// Takes the value out of the Nullable, leaving a `Nullable::Null` in its place.
483    ///
484    /// # Examples
485    ///
486    /// ```
487    /// # use ::swagger::Nullable;
488    ///
489    /// let mut x = Nullable::Present(2);
490    /// x.take();
491    /// assert_eq!(x, Nullable::Null);
492    ///
493    /// let mut x: Nullable<u32> = Nullable::Null;
494    /// x.take();
495    /// assert_eq!(x, Nullable::Null);
496    /// ```
497    #[inline]
498    pub fn take(&mut self) -> Nullable<T> {
499        mem::replace(self, Nullable::Null)
500    }
501}
502
503impl<'a, T: Clone> Nullable<&'a T> {
504    /// Maps an `Nullable<&T>` to an `Nullable<T>` by cloning the contents of the
505    /// Nullable.
506    ///
507    /// # Examples
508    ///
509    /// ```
510    /// # use ::swagger::Nullable;
511    ///
512    /// let x = 12;
513    /// let opt_x = Nullable::Present(&x);
514    /// assert_eq!(opt_x, Nullable::Present(&12));
515    /// let cloned = opt_x.cloned();
516    /// assert_eq!(cloned, Nullable::Present(12));
517    /// ```
518    pub fn cloned(self) -> Nullable<T> {
519        self.map(Clone::clone)
520    }
521}
522
523impl<T: Default> Nullable<T> {
524    /// Returns the contained value or a default
525    ///
526    /// Consumes the `self` argument then, if `Nullable::Present`, returns the contained
527    /// value, otherwise if `Nullable::Null`, returns the default value for that
528    /// type.
529    ///
530    /// # Examples
531    ///
532    /// ```
533    /// # use ::swagger::Nullable;
534    ///
535    /// let x = Nullable::Present(42);
536    /// assert_eq!(42, x.unwrap_or_default());
537    ///
538    /// let y: Nullable<i32> = Nullable::Null;
539    /// assert_eq!(0, y.unwrap_or_default());
540    /// ```
541    #[inline]
542    pub fn unwrap_or_default(self) -> T {
543        match self {
544            Nullable::Present(x) => x,
545            Nullable::Null => Default::default(),
546        }
547    }
548}
549
550// This is a separate function to reduce the code size of .expect() itself.
551#[inline(never)]
552#[cold]
553fn expect_failed(msg: &str) -> ! {
554    panic!("{}", msg)
555}
556
557/////////////////////////////////////////////////////////////////////////////
558// Trait implementations
559/////////////////////////////////////////////////////////////////////////////
560
561impl<T> Default for Nullable<T> {
562    /// Returns None.
563    #[inline]
564    fn default() -> Nullable<T> {
565        Nullable::Null
566    }
567}
568
569impl<T> From<T> for Nullable<T> {
570    fn from(val: T) -> Nullable<T> {
571        Nullable::Present(val)
572    }
573}
574
575#[cfg(feature = "serdejson")]
576impl<T> Serialize for Nullable<T>
577where
578    T: Serialize,
579{
580    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
581    where
582        S: Serializer,
583    {
584        match *self {
585            Nullable::Present(ref inner) => serializer.serialize_some(&inner),
586            Nullable::Null => serializer.serialize_none(),
587        }
588    }
589}
590
591#[cfg(feature = "serdejson")]
592impl<'de, T> Deserialize<'de> for Nullable<T>
593where
594    T: DeserializeOwned,
595{
596    fn deserialize<D>(deserializer: D) -> Result<Nullable<T>, D::Error>
597    where
598        D: Deserializer<'de>,
599    {
600        // In order to deserialize a required, but nullable, value, we first have to check whether
601        // the value is present at all. To do this, we deserialize to a serde_json::Value, which
602        // fails if the value is missing, or gives serde_json::Value::Null if the value is present.
603        // If that succeeds as null, we can easily return a Null.
604        // If that succeeds as some value, we deserialize that value and return a Present.
605        // If that errors, we return the error.
606        let presence: Result<::serde_json::Value, _> =
607            ::serde::Deserialize::deserialize(deserializer);
608        match presence {
609            Ok(::serde_json::Value::Null) => Ok(Nullable::Null),
610            Ok(some_value) => ::serde_json::from_value(some_value)
611                .map(Nullable::Present)
612                .map_err(SerdeError::custom),
613            Err(x) => Err(x),
614        }
615    }
616}
617
618/// Serde helper function to create a default `Option<Nullable<T>>` while
619/// deserializing
620pub fn default_optional_nullable<T>() -> Option<Nullable<T>> {
621    None
622}
623
624/// Serde helper function to deserialize into an `Option<Nullable<T>>`
625#[cfg(feature = "serdejson")]
626pub fn deserialize_optional_nullable<'de, D, T>(
627    deserializer: D,
628) -> Result<Option<Nullable<T>>, D::Error>
629where
630    D: Deserializer<'de>,
631    T: Deserialize<'de>,
632{
633    Option::<T>::deserialize(deserializer).map(|val| match val {
634        Some(inner) => Some(Nullable::Present(inner)),
635        None => Some(Nullable::Null),
636    })
637}
638
639#[cfg(test)]
640#[cfg(feature = "serdejson")]
641mod serde_tests {
642    use super::*;
643    use serde::{Deserialize, Serialize};
644
645    // Set up:
646    #[derive(Clone, Debug, Deserialize, Serialize)]
647    struct NullableStringStruct {
648        item: Nullable<String>,
649    }
650
651    #[derive(Clone, Debug, Deserialize, Serialize)]
652    struct OptionalNullableStringStruct {
653        #[serde(deserialize_with = "deserialize_optional_nullable")]
654        #[serde(default = "default_optional_nullable")]
655        #[serde(skip_serializing_if = "Option::is_none")]
656        item: Option<Nullable<String>>,
657    }
658
659    #[derive(Clone, Debug, Deserialize, Serialize)]
660    struct NullableObjectStruct {
661        item: Nullable<NullableStringStruct>,
662    }
663
664    #[derive(Clone, Debug, Deserialize, Serialize)]
665    struct OptionalNullableObjectStruct {
666        item: Option<Nullable<NullableStringStruct>>,
667    }
668
669    // Helper:
670    macro_rules! round_trip {
671        ($type:ty, $string:expr) => {
672            println!("Original:     {:?}", $string);
673
674            let json: ::serde_json::Value =
675                ::serde_json::from_str($string).expect("Deserialization to JSON Value failed");
676            println!("JSON Value:   {:?}", json);
677
678            let thing: $type =
679                ::serde_json::from_value(json.clone()).expect("Deserialization to struct failed");
680            println!("Struct:       {:?}", thing);
681
682            let json_redux: ::serde_json::Value = ::serde_json::to_value(thing.clone())
683                .expect("Reserialization to JSON Value failed");
684            println!("JSON Redux:   {:?}", json_redux);
685
686            let string_redux =
687                ::serde_json::to_string(&thing).expect("Reserialziation to JSON String failed");
688            println!("String Redux: {:?}", string_redux);
689
690            assert_eq!(
691                $string, string_redux,
692                "Original did not match after round trip"
693            );
694        };
695    }
696
697    // The tests:
698    #[test]
699    fn missing_optionalnullable_value() {
700        let string = "{}";
701        round_trip!(OptionalNullableStringStruct, string);
702    }
703
704    #[test]
705    fn null_optionalnullable_value() {
706        let string = "{\"item\":null}";
707        round_trip!(OptionalNullableStringStruct, string);
708    }
709
710    #[test]
711    fn string_optionalnullable_value() {
712        let string = "{\"item\":\"abc\"}";
713        round_trip!(OptionalNullableStringStruct, string);
714    }
715
716    #[test]
717    fn object_optionalnullable_value() {
718        let string = "{\"item\":{\"item\":\"abc\"}}";
719        round_trip!(OptionalNullableObjectStruct, string);
720    }
721
722    #[test]
723    #[should_panic]
724    fn missing_nullable_value() {
725        let string = "{}";
726        round_trip!(NullableStringStruct, string);
727    }
728
729    #[test]
730    fn null_nullable_value() {
731        let string = "{\"item\":null}";
732        round_trip!(NullableStringStruct, string);
733    }
734
735    #[test]
736    fn string_nullable_value() {
737        let string = "{\"item\":\"abc\"}";
738        round_trip!(NullableStringStruct, string);
739    }
740
741    #[test]
742    fn object_nullable_value() {
743        let string = "{\"item\":{\"item\":\"abc\"}}";
744        round_trip!(NullableObjectStruct, string);
745    }
746}