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}