1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
//! Structured values. #![cfg_attr(value_bag_const_type_id, feature(const_type_id))] #![no_std] #[cfg(any(feature = "std", test))] #[macro_use] #[allow(unused_imports)] extern crate std; #[cfg(not(any(feature = "std", test)))] #[macro_use] #[allow(unused_imports)] extern crate core as std; mod error; mod fill; mod impls; mod internal; #[cfg(test)] mod test; pub use self::{ error::Error, fill::{Fill, Slot}, }; use self::internal::{Inner, Primitive, Visitor}; /// A dynamic structured value. /// /// # Capturing values /// /// There are a few ways to capture a value: /// /// - Using the `ValueBag::capture_*` methods. /// - Using the standard `From` trait. /// - Using the `Fill` API. /// /// ## Using the `ValueBag::capture_*` methods /// /// `ValueBag` offers a few constructor methods that capture values of different kinds. /// These methods require a `T: 'static` to support downcasting. /// /// ``` /// use value_bag::ValueBag; /// /// let value = ValueBag::capture_debug(&42i32); /// /// assert_eq!(Some(42), value.to_i32()); /// ``` /// /// ## Using the standard `From` trait /// /// Standard types that implement `ToValue` also implement `From`. /// /// ``` /// use value_bag::ValueBag; /// /// let value = ValueBag::from(42i32); /// /// assert_eq!(Some(42), value.to_i32()); /// ``` /// /// ``` /// # use std::fmt::Debug; /// use value_bag::ValueBag; /// /// let value = ValueBag::from(&42i32 as &dyn Debug); /// /// assert_eq!(None, value.to_i32()); /// ``` /// /// ## Using the `Fill` API /// /// The `Fill` trait is a way to bridge APIs that may not be directly /// compatible with other constructor methods. /// /// ``` /// use value_bag::{ValueBag, Slot, Fill, Error}; /// /// struct FillSigned; /// /// impl Fill for FillSigned { /// fn fill(&self, slot: &mut Slot) -> Result<(), Error> { /// slot.fill_any(42i32) /// } /// } /// /// let value = ValueBag::from_fill(&FillSigned); /// /// assert_eq!(Some(42), value.to_i32()); /// ``` /// /// ``` /// # use std::fmt::Debug; /// use value_bag::{ValueBag, Slot, Fill, Error}; /// /// struct FillDebug; /// /// impl Fill for FillDebug { /// fn fill(&self, slot: &mut Slot) -> Result<(), Error> { /// slot.fill_debug(&42i32 as &dyn Debug) /// } /// } /// /// let value = ValueBag::from_fill(&FillDebug); /// /// assert_eq!(None, value.to_i32()); /// ``` /// /// # Inspecting values /// /// Once you have a `ValueBag` there are also a few ways to inspect it: /// /// - Using the `Debug`, `Display`, `Serialize`, and `Stream` trait implementations. /// - Using the `ValueBag::to_*` methods. /// - Using the `ValueBag::downcast_ref` method. #[derive(Clone)] pub struct ValueBag<'v> { inner: Inner<'v>, } impl<'v> ValueBag<'v> { /// Get a value from an internal primitive. fn from_primitive<T>(value: T) -> Self where T: Into<Primitive<'v>>, { ValueBag { inner: Inner::Primitive { value: value.into(), }, } } /// Visit the value using an internal visitor. fn visit<'a>(&'a self, visitor: &mut dyn Visitor<'a>) -> Result<(), Error> { self.inner.visit(visitor) } }