tower_sesh/value.rs
1// The code in this module is derived from the `serde_json` crate by @dtolnay.
2// TODO: Discuss notable changes from `serde_json::Value`
3//
4// Dual licensed MIT and Apache 2.0.
5
6//! The `Value` enum, a loosely typed way of representing any session value.
7//!
8//! For more information, see the [documentation for `Value`].
9//!
10//! [documentation for `Value`]: Value
11
12use std::{
13 fmt::{self, Write},
14 mem,
15};
16
17use serde::{de::DeserializeOwned, Deserialize, Serialize};
18
19mod de;
20mod error;
21mod from;
22mod index;
23mod number;
24mod partial_eq;
25mod ser;
26
27pub mod map;
28
29pub use self::error::Error;
30pub use self::index::Index;
31pub use self::map::Map;
32pub use self::number::Number;
33
34/// A loosely typed value that can be stored in a session.
35///
36/// Though this data structure looks quite similar to (and is, in fact, largely
37/// based on) [`serde_json::Value`], there are a few key differences:
38///
39/// - Special floating-point values ([∞][infinity], [−∞][neg-infinity], and
40/// [NaN]) are not implicitly coerced to `Null` in conversion methods.
41/// - Byte arrays are added, enabling more efficient
42/// serialization/deserialization for some data formats.
43///
44/// [`serde_json::Value`]: https://docs.rs/serde_json/latest/serde_json/enum.Value.html
45/// [infinity]: f64::INFINITY
46/// [neg-infinity]: f64::NEG_INFINITY
47/// [NaN]: f64::NAN
48#[derive(Clone, Default, PartialEq, Eq)]
49#[non_exhaustive]
50pub enum Value {
51 #[default]
52 Null,
53 Bool(bool),
54 Number(Number),
55 String(String),
56 ByteArray(Vec<u8>),
57 Array(Vec<Value>),
58 Map(Map<String, Value>),
59}
60
61impl fmt::Debug for Value {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 match self {
64 Value::Null => f.write_str("Null"),
65 Value::Bool(boolean) => f.debug_tuple("Bool").field(boolean).finish(),
66 Value::Number(number) => fmt::Debug::fmt(number, f),
67 Value::String(string) => f.debug_tuple("String").field(string).finish(),
68 Value::ByteArray(bytes) => f
69 .debug_tuple("ByteArray")
70 .field(&DebugByteArray(bytes))
71 .finish(),
72 Value::Array(vec) => f.debug_tuple("Array").field(vec).finish(),
73 Value::Map(map) => f.debug_tuple("Map").field(map).finish(),
74 }
75 }
76}
77
78struct DebugByteArray<'a>(&'a [u8]);
79
80// Copied from https://doc.rust-lang.org/1.84.1/src/core/str/lossy.rs.html#113-145.
81impl fmt::Debug for DebugByteArray<'_> {
82 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83 f.write_char('"')?;
84
85 for chunk in self.0.utf8_chunks() {
86 // Valid part.
87 // Here we partially parse UTF-8 again which is suboptimal.
88 {
89 let valid = chunk.valid();
90 let mut from = 0;
91 for (i, c) in valid.char_indices() {
92 let esc = c.escape_debug();
93 // If char needs escaping, flush backlog so far and write, else skip
94 if esc.len() != 1 {
95 f.write_str(&valid[from..i])?;
96 for c in esc {
97 f.write_char(c)?;
98 }
99 from = i + c.len_utf8();
100 }
101 }
102 f.write_str(&valid[from..])?;
103 }
104
105 // Broken parts of string as hex escape.
106 for &b in chunk.invalid() {
107 write!(f, "\\x{:02X}", b)?;
108 }
109 }
110
111 f.write_char('"')
112 }
113}
114
115impl Value {
116 /// Index into an array or map. A string index can be used to access a value
117 /// in a map, and a `usize` index can be used to access an element of an
118 /// array.
119 ///
120 /// Returns `None` if the type of `self` does not match the type of the
121 /// index, for example if the index is a string and `self` is an array or a
122 /// number. Also returns `None` if the given key does not exist in the map
123 /// or the given index is not within the bounds of the array.
124 ///
125 /// ```
126 /// # use tower_sesh::Value;
127 /// #
128 /// let map = Value::from_iter([("A", 65), ("B", 66), ("C", 64)]);
129 /// assert_eq!(*map.get("A").unwrap(), 65);
130 ///
131 /// let array = Value::from(["A", "B", "C"]);
132 /// assert_eq!(*array.get(2).unwrap(), "C");
133 ///
134 /// assert_eq!(array.get("A"), None);
135 /// ```
136 ///
137 /// Square brackets can also be used to index into a value in a more concise
138 /// way. This returns `Value::Null` in cases where `get` would have returned
139 /// `None`.
140 ///
141 /// ```
142 /// # use tower_sesh::Value;
143 /// #
144 /// let map = Value::from_iter([
145 /// ("A", &["a", "á", "à"] as &[_]),
146 /// ("B", &["b", "b́"]),
147 /// ("C", &["c", "ć", "ć̣", "ḉ"]),
148 /// ]);
149 /// assert_eq!(map["B"][0], "b");
150 ///
151 /// assert_eq!(map["D"], Value::Null);
152 /// assert_eq!(map[0]["x"]["y"]["z"], Value::Null);
153 /// ```
154 pub fn get<I: Index>(&self, index: I) -> Option<&Value> {
155 index.index_into(self)
156 }
157
158 /// Mutably index into an array or map. A string index can be used to access
159 /// a value in a map, and a `usize` index can be used to access an element
160 /// of an array.
161 ///
162 /// Returns `None` if the type of `self` does not match the type of the
163 /// index, for example if the index is a string and `self` is an array or a
164 /// number. Also returns `None` if the given key does not exist in the map
165 /// or the given index is not within the bounds of the array.
166 ///
167 /// ```
168 /// # use tower_sesh::Value;
169 /// #
170 /// let mut map = Value::from_iter([("A", 65), ("B", 66), ("C", 67)]);
171 /// *map.get_mut("A").unwrap() = Value::from(69);
172 ///
173 /// let mut array = Value::from(["A", "B", "C"]);
174 /// *array.get_mut(2).unwrap() = Value::from("D");
175 /// ```
176 pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value> {
177 index.index_into_mut(self)
178 }
179
180 /// Returns `true` if the `Value` is a `Map`. Returns `false` otherwise.
181 ///
182 /// For any `Value` on which `is_map` returns `true`, [`as_map`] and
183 /// [`as_map_mut`] are guaranteed to return the [`Map`] representation.
184 ///
185 /// [`as_map`]: Value::as_map
186 /// [`as_map_mut`]: Value::as_map_mut
187 ///
188 /// ```
189 /// # use tower_sesh::Value;
190 /// #
191 /// let map = Value::from_iter([
192 /// ("a", Value::from_iter([("nested", true)])),
193 /// ("b", Value::from(["an", "array"])),
194 /// ]);
195 ///
196 /// assert!(map.is_map());
197 /// assert!(map["a"].is_map());
198 ///
199 /// assert!(!map["b"].is_map())
200 /// ```
201 pub fn is_map(&self) -> bool {
202 self.as_map().is_some()
203 }
204
205 /// If the `Value` is a `Map`, returns the associated [`Map`]. Returns
206 /// `None` otherwise.
207 ///
208 /// ```
209 /// # use tower_sesh::Value;
210 /// #
211 /// let v = Value::from_iter([
212 /// ("a", Value::from_iter([("nested", true)])),
213 /// ("b", Value::from(["an", "array"])),
214 /// ]);
215 ///
216 /// assert_eq!(v["a"].as_map().unwrap().len(), 1);
217 ///
218 /// assert_eq!(v["b"].as_map(), None);
219 /// ```
220 pub fn as_map(&self) -> Option<&Map<String, Value>> {
221 match self {
222 Value::Map(map) => Some(map),
223 _ => None,
224 }
225 }
226
227 /// If the `Value` is a `Map`, returns the associated mutable [`Map`].
228 /// Returns `None` otherwise.
229 ///
230 /// ```
231 /// # use tower_sesh::{value::Map, Value};
232 /// #
233 /// let mut v = Value::from_iter([
234 /// ("a", Value::from_iter([("nested", true)])),
235 /// ]);
236 ///
237 /// v["a"].as_map_mut().unwrap().clear();
238 /// assert_eq!(v, Value::from_iter([("a", Value::Map(Map::new()))]));
239 /// ```
240 pub fn as_map_mut(&mut self) -> Option<&mut Map<String, Value>> {
241 match self {
242 Value::Map(map) => Some(map),
243 _ => None,
244 }
245 }
246
247 /// Returns `true` if the `Value` is an `Array`. Returns `false` otherwise.
248 ///
249 /// For any `Value` on which `is_array` returns true, [`as_array`] and
250 /// [`as_array_mut`] are guaranteed to return the vector representing the
251 /// array.
252 ///
253 /// **NOTE**: If the `Value` is a `ByteArray`, this method will return
254 /// `false`.
255 ///
256 /// [`as_array`]: Value::as_array
257 /// [`as_array_mut`]: Value::as_array_mut
258 ///
259 /// ```
260 /// # use tower_sesh::Value;
261 /// #
262 /// let map = Value::from_iter([
263 /// ("a", Value::from(["an", "array"])),
264 /// ("b", Value::from_bytes(b"a byte array")),
265 /// ("c", Value::from_iter([("a", "map")])),
266 /// ]);
267 ///
268 /// assert!(map["a"].is_array());
269 ///
270 /// assert!(!map["b"].is_array());
271 /// assert!(!map["c"].is_array());
272 /// ```
273 pub fn is_array(&self) -> bool {
274 self.as_array().is_some()
275 }
276
277 /// If the `Value` is an `Array`, returns the associated vector. Returns
278 /// `None` otherwise.
279 ///
280 /// **NOTE**: If the `Value` is a `ByteArray`, this method will return
281 /// `None`.
282 ///
283 /// ```
284 /// # use tower_sesh::Value;
285 /// #
286 /// let v = Value::from_iter([
287 /// ("a", Value::from(["an", "array"])),
288 /// ("b", Value::from_bytes(b"a byte array")),
289 /// ("c", Value::from_iter([("a", "map")])),
290 /// ]);
291 ///
292 /// assert_eq!(v["a"].as_array().unwrap().len(), 2);
293 ///
294 /// assert_eq!(v["b"].as_array(), None);
295 /// assert_eq!(v["c"].as_array(), None);
296 /// ```
297 pub fn as_array(&self) -> Option<&Vec<Value>> {
298 match self {
299 Value::Array(vec) => Some(vec),
300 _ => None,
301 }
302 }
303
304 /// If the `Value` is an `Array`, returns the associated mutable vector.
305 /// Returns `None` otherwise.
306 ///
307 /// **NOTE**: If the `Value` is a `ByteArray`, this method will return
308 /// `None`.
309 ///
310 /// ```
311 /// # use tower_sesh::{value::Map, Value};
312 /// #
313 /// let mut v = Value::from_iter([
314 /// ("a", ["an", "array"]),
315 /// ]);
316 ///
317 /// v["a"].as_array_mut().unwrap().clear();
318 /// assert_eq!(v, Value::from_iter([("a", &[] as &[&str])]));
319 /// ```
320 pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
321 match self {
322 Value::Array(vec) => Some(vec),
323 _ => None,
324 }
325 }
326
327 /// Returns `true` if the `Value` is a `String`. Returns `false` otherwise.
328 ///
329 /// For any `Value` on which `is_string` returns `true`, [`as_str`] is
330 /// guaranteed to return the string slice.
331 ///
332 /// [`as_str`]: Value::as_str
333 ///
334 /// ```
335 /// # use tower_sesh::Value;
336 /// #
337 /// let v = Value::from_iter([
338 /// ("a", Value::from("some string")),
339 /// ("b", Value::from_bytes(b"some bytes")),
340 /// ("c", Value::from(false)),
341 /// ]);
342 ///
343 /// assert!(v["a"].is_string());
344 ///
345 /// assert!(!v["b"].is_string());
346 /// assert!(!v["c"].is_string());
347 /// ```
348 pub fn is_string(&self) -> bool {
349 self.as_str().is_some()
350 }
351
352 /// If the `Value` is a `String`, returns the associated `str`. Returns
353 /// `None` otherwise.
354 ///
355 /// ```
356 /// # use tower_sesh::Value;
357 /// #
358 /// let v = Value::from_iter([
359 /// ("a", Value::from("some string")),
360 /// ("b", Value::from_bytes(b"some bytes")),
361 /// ("c", Value::from(false)),
362 /// ]);
363 ///
364 /// assert_eq!(v["a"].as_str(), Some("some string"));
365 ///
366 /// assert_eq!(v["b"].as_str(), None);
367 /// assert_eq!(v["c"].as_str(), None);
368 /// ```
369 pub fn as_str(&self) -> Option<&str> {
370 match self {
371 Value::String(s) => Some(s),
372 _ => None,
373 }
374 }
375
376 /// Returns `true` if the `Value` is a `ByteArray`. Returns `false`
377 /// otherwise.
378 ///
379 /// For any `Value` on which `is_bytes` returns `true`, [`as_bytes`] is
380 /// guaranteed to return the byte slice.
381 ///
382 /// [`as_bytes`]: Value::as_bytes
383 ///
384 /// ```
385 /// # use tower_sesh::Value;
386 /// #
387 /// let v = Value::from_iter([
388 /// ("a", Value::from_bytes(b"some bytes")),
389 /// ("b", Value::from(false)),
390 /// ("c", Value::from("some string")),
391 /// ]);
392 ///
393 /// assert!(v["a"].is_bytes());
394 ///
395 /// assert!(!v["b"].is_bytes());
396 /// assert!(!v["c"].is_bytes());
397 /// ```
398 pub fn is_bytes(&self) -> bool {
399 self.as_bytes().is_some()
400 }
401
402 /// If the `Value` is a `ByteArray`, returns the associated `&[u8]`.
403 /// Returns `None` otherwise.
404 ///
405 /// ```
406 /// # use tower_sesh::Value;
407 /// #
408 /// let v = Value::from_iter([
409 /// ("a", Value::from_bytes(b"some bytes")),
410 /// ("b", Value::from(false)),
411 /// ("c", Value::from("some string")),
412 /// ]);
413 ///
414 /// assert_eq!(v["a"].as_bytes(), Some(b"some bytes".as_slice()));
415 ///
416 /// assert_eq!(v["b"].as_bytes(), None);
417 /// assert_eq!(v["c"].as_bytes(), None);
418 /// ```
419 pub fn as_bytes(&self) -> Option<&[u8]> {
420 match self {
421 Value::ByteArray(bytes) => Some(bytes),
422 _ => None,
423 }
424 }
425
426 /// Returns `true` if the `Value` is a `Number`. Returns `false` otherwise.
427 ///
428 /// For any `Value` on which `is_number` returns `true`, [`as_number`] is
429 /// guaranteed to return the [`Number`].
430 ///
431 /// [`as_number`]: Value::as_number
432 ///
433 /// ```
434 /// # use tower_sesh::Value;
435 /// #
436 /// let v = Value::from_iter([
437 /// ("a", Value::from(1)),
438 /// ("b", Value::from("2")),
439 /// ]);
440 ///
441 /// assert!(v["a"].is_number());
442 ///
443 /// assert!(!v["b"].is_number());
444 /// ```
445 pub fn is_number(&self) -> bool {
446 self.as_number().is_some()
447 }
448
449 /// If the `Value` is a `Number`, returns the associated [`Number`]. Returns
450 /// `None` otherwise.
451 ///
452 /// ```
453 /// # use tower_sesh::{value::Number, Value};
454 /// #
455 /// let v = Value::from_iter([
456 /// ("a", Value::from(1)),
457 /// ("b", Value::try_from(2.2f64).unwrap_or_default()),
458 /// ("c", Value::from(-3)),
459 /// ("d", Value::from("4")),
460 /// ]);
461 ///
462 /// assert_eq!(v["a"].as_number(), Some(&Number::from(1u64)));
463 /// assert_eq!(v["b"].as_number(), Some(&Number::from_f64(2.2).unwrap()));
464 /// assert_eq!(v["c"].as_number(), Some(&Number::from(-3i64)));
465 ///
466 /// assert_eq!(v["d"].as_number(), None);
467 /// ```
468 pub fn as_number(&self) -> Option<&Number> {
469 match self {
470 Value::Number(number) => Some(number),
471 _ => None,
472 }
473 }
474
475 /// Returns `true` if the `Value` is an integer between [`i64::MIN`] and
476 /// [`i64::MAX`].
477 ///
478 /// For any `Value` on which `is_i64` returns `true`, [`as_i64`] is
479 /// guaranteed to return the integer value.
480 ///
481 /// [`as_i64`]: Value::as_i64
482 ///
483 /// ```
484 /// # use tower_sesh::Value;
485 /// #
486 /// let big = i64::max_value() as u64 + 10;
487 /// let v = Value::from_iter([
488 /// ("a", Value::from(64)),
489 /// ("b", Value::from(big)),
490 /// ("c", Value::try_from(256.0).unwrap_or_default()),
491 /// ]);
492 ///
493 /// assert!(v["a"].is_i64());
494 ///
495 /// // Greater than `i64::MAX`.
496 /// assert!(!v["b"].is_i64());
497 ///
498 /// // Numbers with a decimal point are not considered integers.
499 /// assert!(!v["c"].is_i64());
500 /// ```
501 pub fn is_i64(&self) -> bool {
502 match self {
503 Value::Number(number) => number.is_i64(),
504 _ => false,
505 }
506 }
507
508 /// Returns `true` if the `Value` is an integer between `0` and
509 /// [`u64::MAX`].
510 ///
511 /// For any `Value` on which `is_u64` returns `true`, [`as_u64`] is
512 /// guaranteed to return the integer value.
513 ///
514 /// [`as_u64`]: Value::as_u64
515 ///
516 /// ```
517 /// # use tower_sesh::Value;
518 /// #
519 /// let v = Value::from_iter([
520 /// ("a", Value::from(64)),
521 /// ("b", Value::from(-64)),
522 /// ("c", Value::try_from(256.0).unwrap_or_default()),
523 /// ]);
524 ///
525 /// assert!(v["a"].is_u64());
526 ///
527 /// // Negative integer.
528 /// assert!(!v["b"].is_u64());
529 ///
530 /// // Numbers with a decimal point are not considered integers.
531 /// assert!(!v["c"].is_u64());
532 /// ```
533 pub fn is_u64(&self) -> bool {
534 match self {
535 Value::Number(number) => number.is_u64(),
536 _ => false,
537 }
538 }
539
540 /// Returns `true` if the `Value` is a number that can be represented by
541 /// `f64`.
542 ///
543 /// For any `Value` on which `is_f64` returns `true`, [`as_f64`] is
544 /// guaranteed to return the floating point value.
545 ///
546 /// This function returns `true` if and only if both [`is_i64`] and
547 /// [`is_u64`] return `false`.
548 ///
549 /// [`as_f64`]: Value::as_f64
550 /// [`is_i64`]: Value::is_i64
551 /// [`is_u64`]: Value::is_u64
552 ///
553 /// ```
554 /// # use tower_sesh::Value;
555 /// #
556 /// let v = Value::from_iter([
557 /// ("a", Value::try_from(256.0).unwrap_or_default()),
558 /// ("b", Value::from(64)),
559 /// ("c", Value::from(-64)),
560 /// ]);
561 ///
562 /// assert!(v["a"].is_f64());
563 ///
564 /// // Integers.
565 /// assert!(!v["b"].is_f64());
566 /// assert!(!v["c"].is_f64());
567 /// ```
568 pub fn is_f64(&self) -> bool {
569 match self {
570 Value::Number(number) => number.is_f64(),
571 _ => false,
572 }
573 }
574
575 /// If the `Value` is an integer, represent it as `i64` if possible. Returns
576 /// `None` otherwise.
577 ///
578 /// ```
579 /// # use tower_sesh::Value;
580 /// #
581 /// let big = i64::max_value() as u64 + 10;
582 /// let v = Value::from_iter([
583 /// ("a", Value::from(64)),
584 /// ("b", Value::from(big)),
585 /// ("c", Value::try_from(256.0).unwrap_or_default()),
586 /// ]);
587 ///
588 /// assert_eq!(v["a"].as_i64(), Some(64));
589 /// assert_eq!(v["b"].as_i64(), None);
590 /// assert_eq!(v["c"].as_i64(), None);
591 /// ```
592 pub fn as_i64(&self) -> Option<i64> {
593 match self {
594 Value::Number(number) => number.as_i64(),
595 _ => None,
596 }
597 }
598
599 /// If the `Value` is an integer, represent it as `u64` if possible. Returns
600 /// `None` otherwise.
601 ///
602 /// ```
603 /// # use tower_sesh::Value;
604 /// #
605 /// let v = Value::from_iter([
606 /// ("a", Value::from(64)),
607 /// ("b", Value::from(-64)),
608 /// ("c", Value::try_from(256.0).unwrap_or_default()),
609 /// ]);
610 ///
611 /// assert_eq!(v["a"].as_u64(), Some(64));
612 /// assert_eq!(v["b"].as_u64(), None);
613 /// assert_eq!(v["c"].as_u64(), None);
614 /// ```
615 pub fn as_u64(&self) -> Option<u64> {
616 match self {
617 Value::Number(number) => number.as_u64(),
618 _ => None,
619 }
620 }
621
622 /// If the `Value` is a number, represent it as `f64` if possible. Returns
623 /// `None` otherwise.
624 ///
625 /// ```
626 /// # use tower_sesh::Value;
627 /// #
628 /// let v = Value::from_iter([
629 /// ("a", Value::try_from(256.0).unwrap_or_default()),
630 /// ("b", Value::from(64)),
631 /// ("c", Value::from(-64)),
632 /// ]);
633 ///
634 /// assert_eq!(v["a"].as_f64(), Some(256.0));
635 /// assert_eq!(v["b"].as_f64(), Some(64.0));
636 /// assert_eq!(v["c"].as_f64(), Some(-64.0));
637 /// ```
638 pub fn as_f64(&self) -> Option<f64> {
639 match self {
640 Value::Number(number) => number.as_f64(),
641 _ => None,
642 }
643 }
644
645 /// Returns `true` if the `Value` is a Boolean. Returns `false` otherwise.
646 ///
647 /// For any `Value` on which `is_boolean` returns `true`, [`as_bool`] is
648 /// guaranteed to return the boolean value.
649 ///
650 /// [`as_bool`]: Value::as_bool
651 ///
652 /// ```
653 /// # use tower_sesh::Value;
654 /// #
655 /// let v = Value::from_iter([
656 /// ("a", Value::from(false)),
657 /// ("b", Value::from("false")),
658 /// ]);
659 ///
660 /// assert!(v["a"].is_boolean());
661 ///
662 /// // The string `"false"` is a string, not a boolean.
663 /// assert!(!v["b"].is_boolean());
664 /// ```
665 pub fn is_boolean(&self) -> bool {
666 self.as_bool().is_some()
667 }
668
669 /// If the `Value` is a Boolean, returns the associated `bool`. Returns
670 /// `None` otherwise.
671 ///
672 /// ```
673 /// # use tower_sesh::Value;
674 /// #
675 /// let v = Value::from_iter([
676 /// ("a", Value::from(false)),
677 /// ("b", Value::from("false")),
678 /// ]);
679 ///
680 /// assert_eq!(v["a"].as_bool(), Some(false));
681 ///
682 /// // The string `"false"` is a string, not a boolean.
683 /// assert_eq!(v["b"].as_bool(), None);
684 /// ```
685 pub fn as_bool(&self) -> Option<bool> {
686 match *self {
687 Value::Bool(b) => Some(b),
688 _ => None,
689 }
690 }
691
692 /// Returns `true` if the `Value` is a `Null`. Returns `false` otherwise.
693 ///
694 /// For any `Value` on which `is_null` returns `true`, [`as_null`] is
695 /// guaranteed to return `Some(())`.
696 ///
697 /// [`as_null`]: Value::as_null
698 ///
699 /// ```
700 /// # use tower_sesh::Value;
701 /// #
702 /// let v = Value::from_iter([
703 /// ("a", Value::Null),
704 /// ("b", Value::try_from(f64::NAN).unwrap_or_default()),
705 /// ("c", Value::from(false)),
706 /// ]);
707 ///
708 /// assert!(v["a"].is_null());
709 /// assert!(v["b"].is_null());
710 ///
711 /// // The boolean `false` is not null.
712 /// assert!(!v["c"].is_null());
713 /// ```
714 pub fn is_null(&self) -> bool {
715 self.as_null().is_some()
716 }
717
718 /// If the `Value` is a `Null`, returns `()`. Returns `None` otherwise.
719 ///
720 /// ```
721 /// # use tower_sesh::Value;
722 /// #
723 /// let v = Value::from_iter([
724 /// ("a", Value::Null),
725 /// ("b", Value::try_from(f64::NAN).unwrap_or_default()),
726 /// ("c", Value::from(false)),
727 /// ]);
728 ///
729 /// assert_eq!(v["a"].as_null(), Some(()));
730 /// assert_eq!(v["b"].as_null(), Some(()));
731 ///
732 /// // The boolean `false` is not null.
733 /// assert_eq!(v["c"].as_null(), None);
734 /// ```
735 pub fn as_null(&self) -> Option<()> {
736 match *self {
737 Value::Null => Some(()),
738 _ => None,
739 }
740 }
741
742 /// Takes the value out of the `Value`, leaving a `Null` in its place.
743 ///
744 /// ```
745 /// # use tower_sesh::Value;
746 /// #
747 /// let mut v = Value::from_iter([("x", "y")]);
748 /// assert_eq!(v["x"].take(), "y");
749 /// assert_eq!(v.get("x"), Some(&Value::Null));
750 /// ```
751 pub fn take(&mut self) -> Value {
752 mem::replace(self, Value::Null)
753 }
754}
755
756impl Value {
757 /// Create a `Value::ByteArray`.
758 ///
759 /// # Examples
760 ///
761 /// ```
762 /// # use tower_sesh::Value;
763 /// #
764 /// let v = Value::from_bytes(b"some bytes");
765 /// let v = Value::from_bytes([82, 117, 115, 116]);
766 /// let v = Value::from_bytes(vec![115, 101, 115, 104]);
767 /// ```
768 pub fn from_bytes<B>(bytes: B) -> Value
769 where
770 B: Into<Vec<u8>>,
771 {
772 Value::ByteArray(bytes.into())
773 }
774}
775
776#[doc(hidden)]
777pub fn to_value<T>(value: T) -> Result<Value, Error>
778where
779 T: Serialize,
780{
781 value.serialize(ser::Serializer)
782}
783
784#[doc(hidden)]
785pub fn from_value<T>(value: Value) -> Result<T, Error>
786where
787 T: DeserializeOwned,
788{
789 T::deserialize(value)
790}
791
792#[doc(hidden)]
793pub fn from_value_borrowed<'de, T>(value: &'de Value) -> Result<T, Error>
794where
795 T: Deserialize<'de>,
796{
797 T::deserialize(value)
798}