summaryrefslogtreecommitdiffstats
path: root/vendor/valuable/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /vendor/valuable/src
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/valuable/src')
-rw-r--r--vendor/valuable/src/enumerable.rs682
-rw-r--r--vendor/valuable/src/field.rs166
-rw-r--r--vendor/valuable/src/lib.rs146
-rw-r--r--vendor/valuable/src/listable.rs257
-rw-r--r--vendor/valuable/src/mappable.rs191
-rw-r--r--vendor/valuable/src/named_values.rs222
-rw-r--r--vendor/valuable/src/slice.rs428
-rw-r--r--vendor/valuable/src/structable.rs496
-rw-r--r--vendor/valuable/src/tuplable.rs339
-rw-r--r--vendor/valuable/src/valuable.rs339
-rw-r--r--vendor/valuable/src/value.rs877
-rw-r--r--vendor/valuable/src/visit.rs459
12 files changed, 4602 insertions, 0 deletions
diff --git a/vendor/valuable/src/enumerable.rs b/vendor/valuable/src/enumerable.rs
new file mode 100644
index 000000000..3161f19f0
--- /dev/null
+++ b/vendor/valuable/src/enumerable.rs
@@ -0,0 +1,682 @@
+use crate::field::*;
+use crate::*;
+
+#[cfg(feature = "alloc")]
+use alloc::format;
+use core::fmt;
+
+/// An enum-like [`Valuable`] sub-type.
+///
+/// Implemented by [`Valuable`] types that have an enum-like shape. Fields may
+/// be named or unnamed (tuple). Values that implement `Enumerable` must return
+/// [`Value::Enumerable`] from their [`Valuable::as_value`] implementation.
+///
+/// # Inspecting
+///
+/// The [`variant()`] method returns the `Enumerable` instance's variant. The
+/// `Enumerable` may also have unnamed fields (tuple) or named fields.
+/// Inspecting the field values is done by visiting the enum. When visiting an
+/// `Enumerable`, either the [`visit_named_fields()`] or the
+/// [`visit_unnamed_fields()`] methods of [`Visit`] are called. Each method may
+/// be called multiple times per `Enumerable`, but the two methods are never
+/// mixed.
+///
+/// [`variant()`]: Enumerable::variant
+/// [`visit_named_fields()`]: Visit::visit_named_fields
+/// [`visit_unnamed_fields()`]: Visit::visit_unnamed_fields
+///
+/// ```
+/// use valuable::{Valuable, Value, Visit};
+///
+/// #[derive(Valuable)]
+/// enum MyEnum {
+/// Foo,
+/// Bar(u32),
+/// }
+///
+/// struct PrintVariant;
+///
+/// impl Visit for PrintVariant {
+/// fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+/// for value in values {
+/// println!(" - {:?}", value);
+/// }
+/// }
+///
+/// fn visit_value(&mut self, value: Value<'_>) {
+/// match value {
+/// Value::Enumerable(v) => {
+/// println!("{}", v.variant().name());
+/// v.visit(self)
+/// }
+/// _ => {}
+/// }
+/// }
+/// }
+///
+/// let my_enum = MyEnum::Bar(123);
+///
+/// valuable::visit(&my_enum, &mut PrintVariant);
+/// ```
+///
+/// If the enum is **statically** defined, then all variants, and variant fields
+/// are known ahead of time and may be accessed via the [`EnumDef`] instance
+/// returned by [`definition()`].
+///
+/// [`definition()`]: Enumerable::definition
+///
+/// # Implementing
+///
+/// Implementing `Enumerable` is usually done by adding `#[derive(Valuable)]` to
+/// a Rust `enum` definition.
+///
+/// ```
+/// use valuable::{Valuable, Enumerable, EnumDef};
+///
+/// #[derive(Valuable)]
+/// enum MyEnum {
+/// Foo,
+/// Bar(u32),
+/// }
+///
+/// let my_enum = MyEnum::Bar(123);
+///
+/// let variants = match my_enum.definition() {
+/// EnumDef::Static { name, variants, .. } => {
+/// assert_eq!("MyEnum", name);
+/// variants
+/// }
+/// _ => unreachable!(),
+/// };
+///
+/// assert_eq!(2, variants.len());
+/// assert_eq!("Foo", variants[0].name());
+/// assert!(variants[0].fields().is_unnamed());
+/// ```
+pub trait Enumerable: Valuable {
+ /// Returns the enum's definition.
+ ///
+ /// See [`EnumDef`] documentation for more details.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Enumerable, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// enum MyEnum {
+ /// Foo,
+ /// Bar(u32),
+ /// }
+ ///
+ /// let my_enum = MyEnum::Bar(123);
+ ///
+ /// assert_eq!("MyEnum", my_enum.definition().name());
+ /// ```
+ fn definition(&self) -> EnumDef<'_>;
+
+ /// Returns the `enum`'s current variant.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Enumerable, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// enum MyEnum {
+ /// Foo,
+ /// Bar(u32),
+ /// }
+ ///
+ /// let my_enum = MyEnum::Foo;
+ /// assert_eq!("Foo", my_enum.variant().name());
+ /// ```
+ fn variant(&self) -> Variant<'_>;
+}
+
+/// An enum's variants, variant fields, and other enum-level information.
+///
+/// Returned by [`Enumerable::definition()`], `EnumDef` provides the caller with
+/// information about the enum's definition.
+#[non_exhaustive]
+#[derive(Debug)]
+pub enum EnumDef<'a> {
+ /// The enum is statically-defined, all variants and variant-level fields
+ /// are known ahead of time.
+ ///
+ /// Most `Enumerable` definitions for Rust enum types will be
+ /// `EnumDef::Static`.
+ ///
+ /// # Examples
+ ///
+ /// A statically defined enum
+ ///
+ /// ```
+ /// use valuable::{Valuable, Enumerable, EnumDef};
+ ///
+ /// #[derive(Valuable)]
+ /// enum MyEnum {
+ /// Foo,
+ /// Bar(u32),
+ /// }
+ ///
+ /// let my_enum = MyEnum::Bar(123);
+ ///
+ /// let variants = match my_enum.definition() {
+ /// EnumDef::Static { name, variants, .. } => {
+ /// assert_eq!("MyEnum", name);
+ /// variants
+ /// }
+ /// _ => unreachable!(),
+ /// };
+ ///
+ /// assert_eq!(2, variants.len());
+ /// assert_eq!("Foo", variants[0].name());
+ /// assert_eq!("Bar", variants[1].name());
+ /// ```
+ #[non_exhaustive]
+ Static {
+ /// The enum's name
+ name: &'static str,
+
+ /// The enum's variants
+ variants: &'static [VariantDef<'static>],
+ },
+
+ /// The enum is dynamically-defined, not all variants and fields are known
+ /// ahead of time.
+ ///
+ /// # Examples
+ ///
+ /// The enum variant is tracked as a string
+ ///
+ /// ```
+ /// use valuable::{Enumerable, EnumDef, Fields, VariantDef, Valuable, Value, Variant, Visit};
+ ///
+ /// /// A dynamic enum
+ /// struct DynEnum {
+ /// // The enum name
+ /// name: String,
+ ///
+ /// // The current variant
+ /// variant: String,
+ /// }
+ ///
+ /// impl Valuable for DynEnum {
+ /// fn as_value(&self) -> Value<'_> {
+ /// Value::Enumerable(self)
+ /// }
+ ///
+ /// fn visit(&self, _visit: &mut dyn Visit) {
+ /// // No variant fields, so there is nothing to call here.
+ /// }
+ /// }
+ ///
+ /// impl Enumerable for DynEnum {
+ /// fn definition(&self) -> EnumDef<'_> {
+ /// EnumDef::new_dynamic(&self.name, &[])
+ /// }
+ ///
+ /// fn variant(&self) -> Variant<'_> {
+ /// Variant::Dynamic(VariantDef::new(&self.variant, Fields::Unnamed(0)))
+ /// }
+ /// }
+ /// ```
+ #[non_exhaustive]
+ Dynamic {
+ /// The enum's name
+ name: &'a str,
+
+ /// The enum's variants
+ variants: &'a [VariantDef<'a>],
+ },
+}
+
+/// An enum variant definition.
+///
+/// Included with [`EnumDef`] returned by [`Enumerable::definition()`],
+/// `VariantDef` provides the caller with information about a specific variant.
+#[derive(Debug)]
+pub struct VariantDef<'a> {
+ /// Variant name
+ name: &'a str,
+
+ /// Variant fields
+ fields: Fields<'a>,
+}
+
+/// An enum variant
+///
+/// Returned by [`Enumerable::variant()`], `Variant` represents a single enum
+/// variant.
+#[derive(Debug)]
+pub enum Variant<'a> {
+ /// The variant is statically defined by the associated enum.
+ Static(&'static VariantDef<'static>),
+
+ /// The variant is dynamically defined and not included as part of
+ /// [`Enumerable::definition()`].
+ Dynamic(VariantDef<'a>),
+}
+
+impl<'a> EnumDef<'a> {
+ /// Create a new [`EnumDef::Static`] instance.
+ ///
+ /// This should be used when an enum's variants are fixed and known ahead of
+ /// time.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{EnumDef, Fields, VariantDef};
+ ///
+ /// static VARIANTS: &[VariantDef<'static>] = &[
+ /// VariantDef::new("Bar", Fields::Unnamed(1)),
+ /// ];
+ ///
+ /// let def = EnumDef::new_static( "Foo", VARIANTS);
+ /// ```
+ pub const fn new_static(
+ name: &'static str,
+ variants: &'static [VariantDef<'static>],
+ ) -> EnumDef<'a> {
+ EnumDef::Static { name, variants }
+ }
+
+ /// Create a new [`EnumDef::Dynamic`] instance.
+ ///
+ /// This is used when the enum's variants may vary at runtime.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{EnumDef, Fields, VariantDef};
+ ///
+ /// let def = EnumDef::new_dynamic(
+ /// "Foo",
+ /// &[VariantDef::new("Bar", Fields::Unnamed(1))]
+ /// );
+ /// ```
+ pub const fn new_dynamic(name: &'a str, variants: &'a [VariantDef<'a>]) -> EnumDef<'a> {
+ EnumDef::Dynamic { name, variants }
+ }
+
+ /// Returns the enum's name
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Enumerable, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// enum Foo {
+ /// Bar,
+ /// Baz,
+ /// }
+ ///
+ /// let def = Foo::Bar.definition();
+ /// assert_eq!("Foo", def.name());
+ /// ```
+ pub fn name(&self) -> &str {
+ match self {
+ EnumDef::Static { name, .. } => name,
+ EnumDef::Dynamic { name, .. } => name,
+ }
+ }
+
+ /// Returns the enum's variants
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Enumerable, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// enum Foo {
+ /// Bar,
+ /// Baz,
+ /// }
+ ///
+ /// let def = Foo::Bar.definition();
+ /// let variants = def.variants();
+ ///
+ /// assert_eq!(2, variants.len());
+ /// assert_eq!("Bar", variants[0].name());
+ /// ```
+ pub fn variants(&self) -> &[VariantDef<'_>] {
+ match self {
+ EnumDef::Static { variants, .. } => variants,
+ EnumDef::Dynamic { variants, .. } => variants,
+ }
+ }
+
+ /// Returns `true` if the enum is [statically defined](EnumDef::Static).
+ ///
+ /// # Examples
+ ///
+ /// With a static enum
+ ///
+ /// ```
+ /// use valuable::{Enumerable, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// enum Foo {
+ /// Bar,
+ /// Baz,
+ /// }
+ ///
+ /// let def = Foo::Bar.definition();
+ /// assert!(def.is_static());
+ /// ```
+ ///
+ /// With a dynamic enum
+ ///
+ /// ```
+ /// use valuable::{EnumDef, Fields, VariantDef};
+ ///
+ /// let def = EnumDef::new_dynamic("Foo", &[]);
+ /// assert!(!def.is_static());
+ /// ```
+ pub fn is_static(&self) -> bool {
+ matches!(self, EnumDef::Static { .. })
+ }
+
+ /// Returns `true` if the enum is [dynamically defined](EnumDef::Dynamic).
+ ///
+ /// # Examples
+ ///
+ /// With a static enum
+ ///
+ /// ```
+ /// use valuable::{Enumerable, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// enum Foo {
+ /// Bar,
+ /// Baz,
+ /// }
+ ///
+ /// let def = Foo::Bar.definition();
+ /// assert!(!def.is_dynamic());
+ /// ```
+ ///
+ /// With a dynamic enum
+ ///
+ /// ```
+ /// use valuable::{EnumDef, Fields, VariantDef};
+ ///
+ /// let def = EnumDef::new_dynamic("Foo", &[]);
+ /// assert!(def.is_dynamic());
+ /// ```
+ pub fn is_dynamic(&self) -> bool {
+ matches!(self, EnumDef::Dynamic { .. })
+ }
+}
+
+impl<'a> VariantDef<'a> {
+ /// Creates a new `VariantDef` instance.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Fields, VariantDef};
+ ///
+ /// let def = VariantDef::new("Foo", Fields::Unnamed(2));
+ /// ```
+ pub const fn new(name: &'a str, fields: Fields<'a>) -> VariantDef<'a> {
+ VariantDef { name, fields }
+ }
+
+ /// Returns the variant's name
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Fields, VariantDef};
+ ///
+ /// let def = VariantDef::new("Foo", Fields::Unnamed(2));
+ /// assert_eq!("Foo", def.name());
+ /// ```
+ pub fn name(&self) -> &str {
+ self.name
+ }
+
+ /// Returns the variant's fields
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Fields, VariantDef};
+ ///
+ /// let def = VariantDef::new("Foo", Fields::Unnamed(3));
+ /// assert!(matches!(def.fields(), Fields::Unnamed(_)));
+ /// ```
+ pub fn fields(&self) -> &Fields<'_> {
+ &self.fields
+ }
+}
+
+impl Variant<'_> {
+ /// Returns the variant's name
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Fields, Variant, VariantDef};
+ ///
+ /// static VARIANT: &VariantDef<'static> = &VariantDef::new(
+ /// "Foo", Fields::Unnamed(2));
+ ///
+ /// let variant = Variant::Static(VARIANT);
+ /// assert_eq!("Foo", variant.name());
+ /// ```
+ pub fn name(&self) -> &str {
+ match self {
+ Variant::Static(v) => v.name(),
+ Variant::Dynamic(v) => v.name(),
+ }
+ }
+
+ /// Returns the variant's fields
+ pub fn fields(&self) -> &Fields<'_> {
+ match self {
+ Variant::Static(v) => v.fields(),
+ Variant::Dynamic(v) => v.fields(),
+ }
+ }
+
+ /// Returns `true` if the variant has associated named fields.
+ ///
+ /// # Examples
+ ///
+ /// With named fields
+ ///
+ /// ```
+ /// use valuable::{Fields, NamedField, Variant, VariantDef};
+ ///
+ /// static VARIANT: &VariantDef<'static> = &VariantDef::new(
+ /// "Foo", Fields::Named(&[NamedField::new("hello")]));
+ ///
+ /// let variant = Variant::Static(VARIANT);
+ /// assert!(variant.is_named_fields());
+ /// ```
+ ///
+ /// With unnamed fields
+ ///
+ /// ```
+ /// use valuable::{Fields, Variant, VariantDef};
+ ///
+ /// static VARIANT: &VariantDef<'static> = &VariantDef::new(
+ /// "Foo", Fields::Unnamed(1));
+ ///
+ /// let variant = Variant::Static(VARIANT);
+ /// assert!(!variant.is_named_fields());
+ /// ```
+ pub fn is_named_fields(&self) -> bool {
+ self.fields().is_named()
+ }
+
+ /// Returns `true` if the variant has associated unnamed fields.
+ ///
+ /// # Examples
+ ///
+ /// With named fields
+ ///
+ /// ```
+ /// use valuable::{Fields, NamedField, Variant, VariantDef};
+ ///
+ /// static VARIANT: &VariantDef<'static> = &VariantDef::new(
+ /// "Foo", Fields::Named(&[NamedField::new("hello")]));
+ ///
+ /// let variant = Variant::Static(VARIANT);
+ /// assert!(!variant.is_unnamed_fields());
+ /// ```
+ ///
+ /// With unnamed fields
+ ///
+ /// ```
+ /// use valuable::{Fields, Variant, VariantDef};
+ ///
+ /// static VARIANT: &VariantDef<'static> = &VariantDef::new(
+ /// "Foo", Fields::Unnamed(1));
+ ///
+ /// let variant = Variant::Static(VARIANT);
+ /// assert!(variant.is_unnamed_fields());
+ /// ```
+ pub fn is_unnamed_fields(&self) -> bool {
+ !self.is_named_fields()
+ }
+}
+
+impl fmt::Debug for dyn Enumerable + '_ {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let variant = self.variant();
+ #[cfg(feature = "alloc")]
+ let name = format!("{}::{}", self.definition().name(), variant.name());
+ #[cfg(not(feature = "alloc"))]
+ let name = variant.name();
+
+ if variant.is_named_fields() {
+ struct DebugEnum<'a, 'b> {
+ fmt: fmt::DebugStruct<'a, 'b>,
+ }
+
+ let mut debug = DebugEnum {
+ fmt: fmt.debug_struct(&name),
+ };
+
+ impl Visit for DebugEnum<'_, '_> {
+ fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
+ for (field, value) in named_values {
+ self.fmt.field(field.name(), value);
+ }
+ }
+
+ fn visit_value(&mut self, _: Value<'_>) {
+ unreachable!();
+ }
+ }
+
+ self.visit(&mut debug);
+
+ debug.fmt.finish()
+ } else {
+ struct DebugEnum<'a, 'b> {
+ fmt: fmt::DebugTuple<'a, 'b>,
+ }
+
+ let mut debug = DebugEnum {
+ fmt: fmt.debug_tuple(&name),
+ };
+
+ impl Visit for DebugEnum<'_, '_> {
+ fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+ for value in values {
+ self.fmt.field(value);
+ }
+ }
+
+ fn visit_value(&mut self, _: Value<'_>) {
+ unreachable!();
+ }
+ }
+
+ self.visit(&mut debug);
+
+ debug.fmt.finish()
+ }
+ }
+}
+
+macro_rules! deref {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<T: ?Sized + Enumerable> Enumerable for $ty {
+ fn definition(&self) -> EnumDef<'_> {
+ T::definition(&**self)
+ }
+
+ fn variant(&self) -> Variant<'_> {
+ T::variant(&**self)
+ }
+ }
+ )*
+ };
+}
+
+deref! {
+ &T,
+ &mut T,
+ #[cfg(feature = "alloc")]
+ alloc::boxed::Box<T>,
+ #[cfg(feature = "alloc")]
+ alloc::rc::Rc<T>,
+ #[cfg(not(valuable_no_atomic_cas))]
+ #[cfg(feature = "alloc")]
+ alloc::sync::Arc<T>,
+}
+
+static RESULT_VARIANTS: &[VariantDef<'static>] = &[
+ VariantDef::new("Ok", Fields::Unnamed(1)),
+ VariantDef::new("Err", Fields::Unnamed(1)),
+];
+
+impl<T, E> Enumerable for Result<T, E>
+where
+ T: Valuable,
+ E: Valuable,
+{
+ fn definition(&self) -> EnumDef<'_> {
+ EnumDef::new_static("Result", RESULT_VARIANTS)
+ }
+
+ fn variant(&self) -> Variant<'_> {
+ match self {
+ Ok(_) => Variant::Static(&RESULT_VARIANTS[0]),
+ Err(_) => Variant::Static(&RESULT_VARIANTS[1]),
+ }
+ }
+}
+
+impl<T, E> Valuable for Result<T, E>
+where
+ T: Valuable,
+ E: Valuable,
+{
+ fn as_value(&self) -> Value<'_> {
+ Value::Enumerable(self)
+ }
+
+ fn visit(&self, visitor: &mut dyn Visit) {
+ match self {
+ Ok(val) => visitor.visit_unnamed_fields(&[val.as_value()]),
+ Err(val) => visitor.visit_unnamed_fields(&[val.as_value()]),
+ }
+ }
+}
diff --git a/vendor/valuable/src/field.rs b/vendor/valuable/src/field.rs
new file mode 100644
index 000000000..faa00f420
--- /dev/null
+++ b/vendor/valuable/src/field.rs
@@ -0,0 +1,166 @@
+/// Data stored within a `Structable` or an `Enumerable`.
+#[derive(Debug)]
+pub enum Fields<'a> {
+ /// Named fields
+ Named(&'a [NamedField<'a>]),
+
+ /// Unnamed (positional) fields or unit
+ ///
+ /// The `usize` value represents the number of fields.
+ Unnamed(usize),
+}
+
+/// A named field
+#[derive(Debug, Clone, Copy)]
+pub struct NamedField<'a>(&'a str);
+
+impl Fields<'_> {
+ /// Returns `true` if the fields are named.
+ ///
+ /// # Examples
+ ///
+ /// Named fields
+ ///
+ /// ```
+ /// use valuable::Fields;
+ ///
+ /// let fields = Fields::Named(&[]);
+ /// assert!(fields.is_named());
+ /// ```
+ ///
+ /// Unnamed fields
+ ///
+ /// ```
+ /// use valuable::Fields;
+ ///
+ /// let fields = Fields::Unnamed(2);
+ /// assert!(!fields.is_named());
+ /// ```
+ pub const fn is_named(&self) -> bool {
+ matches!(self, Fields::Named(..))
+ }
+
+ /// Returns `true` if the fields are unnamed.
+ ///
+ /// # Examples
+ ///
+ /// Named fields
+ ///
+ /// ```
+ /// use valuable::Fields;
+ ///
+ /// let fields = Fields::Named(&[]);
+ /// assert!(!fields.is_unnamed());
+ /// ```
+ ///
+ /// Unnamed fields
+ ///
+ /// ```
+ /// use valuable::Fields;
+ ///
+ /// let fields = Fields::Unnamed(3);
+ /// assert!(fields.is_unnamed());
+ /// ```
+ pub const fn is_unnamed(&self) -> bool {
+ matches!(self, Fields::Unnamed(_))
+ }
+
+ /// Returns the number of fields.
+ ///
+ /// # Examples
+ ///
+ /// Named fields
+ ///
+ /// ```
+ /// use valuable::{Fields, NamedField};
+ ///
+ /// let fields = &[
+ /// NamedField::new("alice"),
+ /// NamedField::new("bob"),
+ /// ];
+ /// let fields = Fields::Named(fields);
+ ///
+ /// assert_eq!(fields.len(), 2);
+ /// ```
+ ///
+ /// Unnamed fields
+ ///
+ /// ```
+ /// use valuable::Fields;
+ ///
+ /// let fields = Fields::Unnamed(2);
+ /// assert_eq!(fields.len(), 2);
+ /// ```
+ pub const fn len(&self) -> usize {
+ match self {
+ Self::Named(names) => names.len(),
+ Self::Unnamed(len) => *len,
+ }
+ }
+
+ /// Returns `true` if this set of fields defines no fields.
+ ///
+ /// # Examples
+ ///
+ /// Named fields
+ ///
+ /// ```
+ /// use valuable::{Fields, NamedField};
+ ///
+ /// let fields = &[
+ /// NamedField::new("alice"),
+ /// NamedField::new("bob"),
+ /// ];
+ /// let non_empty = Fields::Named(fields);
+ ///
+ /// let empty = Fields::Named(&[]);
+ ///
+ /// assert!(!non_empty.is_empty());
+ /// assert!(empty.is_empty());
+ /// ```
+ ///
+ /// Unnamed fields
+ ///
+ /// ```
+ /// use valuable::Fields;
+ ///
+ /// let non_empty = Fields::Unnamed(2);
+ /// let empty = Fields::Unnamed(0);
+ ///
+ /// assert!(!non_empty.is_empty());
+ /// assert!(empty.is_empty());
+ /// ```
+ pub const fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+}
+
+impl<'a> NamedField<'a> {
+ /// Create a new `NamedField` instance with the given name.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::NamedField;
+ ///
+ /// let field = NamedField::new("hello");
+ /// assert_eq!("hello", field.name());
+ /// ```
+ pub const fn new(name: &'a str) -> NamedField<'a> {
+ NamedField(name)
+ }
+
+ /// Returns the field name
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::NamedField;
+ ///
+ /// let field = NamedField::new("hello");
+ /// assert_eq!("hello", field.name());
+ /// ```
+ pub const fn name(&self) -> &str {
+ self.0
+ }
+}
diff --git a/vendor/valuable/src/lib.rs b/vendor/valuable/src/lib.rs
new file mode 100644
index 000000000..5ba6341a0
--- /dev/null
+++ b/vendor/valuable/src/lib.rs
@@ -0,0 +1,146 @@
+#![warn(
+ missing_debug_implementations,
+ missing_docs,
+ rust_2018_idioms,
+ unreachable_pub
+)]
+//! Valuable provides object-safe value inspection. Use cases include passing
+//! structured data to trait objects and object-safe serialization.
+//!
+//! # Getting started
+//!
+//! First, derive [`Valuable`][macro@crate::Valuable] on your types.
+//!
+//! ```
+//! use valuable::Valuable;
+//!
+//! #[derive(Valuable)]
+//! struct HelloWorld {
+//! message: Message,
+//! }
+//!
+//! #[derive(Valuable)]
+//! enum Message {
+//! HelloWorld,
+//! Custom(String),
+//! }
+//! ```
+//!
+//! Then, implement a [visitor][Visit] to inspect the data.
+//!
+//! ```
+//! use valuable::{NamedValues, Value, Valuable, Visit};
+//!
+//! struct Print;
+//!
+//! impl Visit for Print {
+//! fn visit_value(&mut self, value: Value<'_>) {
+//! match value {
+//! Value::Structable(v) => {
+//! println!("struct {}", v.definition().name());
+//! v.visit(self);
+//! }
+//! Value::Enumerable(v) => {
+//! println!("enum {}::{}", v.definition().name(), v.variant().name());
+//! v.visit(self);
+//! }
+//! Value::Listable(v) => {
+//! println!("list");
+//! v.visit(self);
+//! }
+//! Value::Mappable(v) => {
+//! println!("map");
+//! v.visit(self);
+//! }
+//! _ => {
+//! println!("value {:?}", value);
+//! }
+//! }
+//! }
+//!
+//! fn visit_named_fields(&mut self, named_fields: &NamedValues<'_>) {
+//! for (field, value) in named_fields.iter() {
+//! println!("named field {}", field.name());
+//! value.visit(self);
+//! }
+//! }
+//!
+//! fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+//! for value in values {
+//! value.visit(self);
+//! }
+//! }
+//!
+//! fn visit_entry(&mut self, key: Value<'_>, value: Value<'_>) {
+//! println!("key / value");
+//! key.visit(self);
+//! value.visit(self);
+//! }
+//! }
+//! ```
+//!
+//! Then, use the visitor to visit the value.
+//!
+//! ```
+//! # use valuable::*;
+//! # #[derive(Valuable)]
+//! # struct HelloWorld { message: Message }
+//! # #[derive(Valuable)]
+//! # enum Message { HelloWorld }
+//! # struct Print;
+//! # impl Visit for Print {
+//! # fn visit_value(&mut self, _: Value<'_>) {}
+//! # }
+//! let hello_world = HelloWorld { message: Message::HelloWorld };
+//! hello_world.visit(&mut Print);
+//! ```
+
+#![cfg_attr(not(feature = "std"), no_std)]
+#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg, doc_cfg_hide))]
+#![cfg_attr(
+ docsrs,
+ doc(cfg_hide(
+ not(valuable_no_atomic_cas),
+ not(valuable_no_atomic),
+ not(valuable_no_atomic_64)
+ ))
+)]
+
+#[cfg(feature = "alloc")]
+extern crate alloc;
+
+mod enumerable;
+pub use enumerable::{EnumDef, Enumerable, Variant, VariantDef};
+
+mod field;
+pub use field::{Fields, NamedField};
+
+mod listable;
+pub use listable::Listable;
+
+mod mappable;
+pub use mappable::Mappable;
+
+mod named_values;
+pub use named_values::NamedValues;
+
+mod slice;
+pub use slice::Slice;
+
+mod structable;
+pub use structable::{StructDef, Structable};
+
+mod tuplable;
+pub use tuplable::{Tuplable, TupleDef};
+
+mod valuable;
+pub use crate::valuable::Valuable;
+
+mod value;
+pub use value::Value;
+
+mod visit;
+pub use visit::{visit, Visit};
+
+#[cfg(feature = "derive")]
+pub use valuable_derive::Valuable;
diff --git a/vendor/valuable/src/listable.rs b/vendor/valuable/src/listable.rs
new file mode 100644
index 000000000..b79317f9c
--- /dev/null
+++ b/vendor/valuable/src/listable.rs
@@ -0,0 +1,257 @@
+use crate::*;
+
+use core::fmt;
+
+/// A list-like [`Valuable`] sub-type.
+///
+/// Implemented by [`Valuable`] types that have a list-like shape. This includes
+/// [`Vec`] and other Rust [collection] types. `Listable` types may or may not
+/// store items in contiguous memory. Any type that implements [`IntoIterator`]
+/// may implement `Listable`. Values that implement `Listable` must return
+/// [`Value::Listable`] from their [`Valuable::as_value`] implementation.
+///
+/// [collection]: https://doc.rust-lang.org/stable/std/collections/index.html
+///
+/// # Inspecting
+///
+/// Inspecting `Listable` items is done by visiting the collection. When
+/// visiting a `Listable`, contained values are either passed one-by-one by
+/// repeatedly calling [`visit_value()`] or all at once by calling
+/// [`visit_primitive_slice()`]. The [`visit_primitive_slice()`] method has
+/// lower overhead but can only be used when the `Listable` type contains
+/// primitive values.
+///
+/// See [`Visit`] documentation for more details.
+///
+/// # Implementing
+///
+/// If the type stores values in slices internally, then those slices are passed
+/// to [`Valuable::visit_slice`], which handles calling
+/// [`visit_primitive_slice()`] if possible.
+///
+/// [`visit_value()`]: Visit::visit_value
+/// [`visit_primitive_slice()`]: Visit::visit_primitive_slice
+///
+/// ```
+/// use valuable::{Listable, Valuable, Value, Visit};
+///
+/// struct MyCollection<T> {
+/// chunks: Vec<Vec<T>>,
+/// }
+///
+/// impl<T: Valuable> Valuable for MyCollection<T> {
+/// fn as_value(&self) -> Value<'_> {
+/// Value::Listable(self)
+/// }
+///
+/// fn visit(&self, visit: &mut dyn Visit) {
+/// for chunk in &self.chunks {
+/// // Handles visiting the slice
+/// Valuable::visit_slice(chunk, visit);
+/// }
+/// }
+/// }
+///
+/// impl<T: Valuable> Listable for MyCollection<T> {
+/// fn size_hint(&self) -> (usize, Option<usize>) {
+/// let len = self.chunks.iter().map(|chunk| chunk.len()).sum();
+/// (len, Some(len))
+/// }
+/// }
+/// ```
+pub trait Listable: Valuable {
+ /// Returns the bounds on the remaining length of the `Listable`.
+ ///
+ /// Specifically, `size_hint()` returns a tuple where the first element
+ /// is the lower bound, and the second element is the upper bound.
+ ///
+ /// The second half of the tuple that is returned is an [`Option`]`<`[`usize`]`>`.
+ /// A [`None`] here means that either there is no known upper bound, or the
+ /// upper bound is larger than [`usize`].
+ ///
+ /// # Implementation notes
+ ///
+ /// It is not enforced that a `Listable` implementation yields the declared
+ /// number of elements. A buggy iterator may yield less than the lower bound
+ /// or more than the upper bound of elements.
+ ///
+ /// `size_hint()` is primarily intended to be used for optimizations such as
+ /// reserving space for the elements of the `Listable`, but must not be
+ /// trusted to e.g., omit bounds checks in unsafe code. An incorrect
+ /// implementation of `size_hint()` should not lead to memory safety
+ /// violations.
+ ///
+ /// That said, the implementation should provide a correct estimation,
+ /// because otherwise it would be a violation of the trait's protocol.
+ ///
+ /// [`usize`]: type@usize
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// use valuable::Listable;
+ ///
+ /// let a = vec![1, 2, 3];
+ ///
+ /// assert_eq!((3, Some(3)), a.size_hint());
+ /// ```
+ fn size_hint(&self) -> (usize, Option<usize>);
+}
+
+macro_rules! deref {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<T: ?Sized + Listable> Listable for $ty {
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ T::size_hint(&**self)
+ }
+ }
+ )*
+ };
+}
+
+deref! {
+ &T,
+ &mut T,
+ #[cfg(feature = "alloc")]
+ alloc::boxed::Box<T>,
+ #[cfg(feature = "alloc")]
+ alloc::rc::Rc<T>,
+ #[cfg(not(valuable_no_atomic_cas))]
+ #[cfg(feature = "alloc")]
+ alloc::sync::Arc<T>,
+}
+
+macro_rules! slice {
+ (
+ $(
+ $(#[$attrs:meta])*
+ ($($generics:tt)*) $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<$($generics)*> Valuable for $ty {
+ fn as_value(&self) -> Value<'_> {
+ Value::Listable(self as &dyn Listable)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ T::visit_slice(self, visit);
+ }
+ }
+
+ $(#[$attrs])*
+ impl<$($generics)*> Listable for $ty {
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (self.len(), Some(self.len()))
+ }
+ }
+ )*
+ };
+}
+
+slice! {
+ (T: Valuable) &'_ [T],
+ #[cfg(feature = "alloc")]
+ (T: Valuable) alloc::boxed::Box<[T]>,
+ #[cfg(feature = "alloc")]
+ (T: Valuable) alloc::rc::Rc<[T]>,
+ #[cfg(not(valuable_no_atomic_cas))]
+ #[cfg(feature = "alloc")]
+ (T: Valuable) alloc::sync::Arc<[T]>,
+ (T: Valuable, const N: usize) [T; N],
+ #[cfg(feature = "alloc")]
+ (T: Valuable) alloc::vec::Vec<T>,
+}
+
+macro_rules! collection {
+ (
+ $(
+ $(#[$attrs:meta])*
+ ($($generics:tt)*) $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<$($generics)*> Valuable for $ty {
+ fn as_value(&self) -> Value<'_> {
+ Value::Listable(self as &dyn Listable)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ for value in self.iter() {
+ visit.visit_value(value.as_value());
+ }
+ }
+ }
+
+ $(#[$attrs])*
+ impl<$($generics)*> Listable for $ty {
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (self.len(), Some(self.len()))
+ }
+ }
+ )*
+ };
+}
+
+collection! {
+ #[cfg(feature = "alloc")]
+ (T: Valuable) alloc::collections::LinkedList<T>,
+ #[cfg(feature = "alloc")]
+ (T: Valuable + Ord) alloc::collections::BinaryHeap<T>,
+ #[cfg(feature = "alloc")]
+ (T: Valuable + Ord) alloc::collections::BTreeSet<T>,
+ #[cfg(feature = "std")]
+ (T: Valuable + Eq + std::hash::Hash, H: std::hash::BuildHasher) std::collections::HashSet<T, H>,
+}
+
+#[cfg(feature = "alloc")]
+impl<T: Valuable> Valuable for alloc::collections::VecDeque<T> {
+ fn as_value(&self) -> Value<'_> {
+ Value::Listable(self as &dyn Listable)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ let (first, second) = self.as_slices();
+ T::visit_slice(first, visit);
+ T::visit_slice(second, visit);
+ }
+}
+
+#[cfg(feature = "alloc")]
+impl<T: Valuable> Listable for alloc::collections::VecDeque<T> {
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (self.len(), Some(self.len()))
+ }
+}
+
+impl fmt::Debug for dyn Listable + '_ {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ struct DebugListable<'a, 'b> {
+ fmt: fmt::DebugList<'a, 'b>,
+ }
+
+ impl Visit for DebugListable<'_, '_> {
+ fn visit_value(&mut self, value: Value<'_>) {
+ self.fmt.entry(&value);
+ }
+ }
+
+ let mut debug = DebugListable {
+ fmt: fmt.debug_list(),
+ };
+
+ self.visit(&mut debug);
+ debug.fmt.finish()
+ }
+}
diff --git a/vendor/valuable/src/mappable.rs b/vendor/valuable/src/mappable.rs
new file mode 100644
index 000000000..c7c30bf0b
--- /dev/null
+++ b/vendor/valuable/src/mappable.rs
@@ -0,0 +1,191 @@
+use crate::*;
+
+use core::fmt;
+
+/// A map-like [`Valuable`] sub-type.
+///
+/// Implemented by [`Valuable`] types that have a map-like shape. This includes
+/// [`HashMap`] and other Rust [collection] types. Values that implement
+/// `Mappable` must return [`Value::Mappable`] from their [`Value::as_value`]
+/// implementation.
+///
+/// [collection]: https://doc.rust-lang.org/stable/std/collections/index.html
+///
+/// # Inspecting
+///
+/// Inspecting `Mappable` entries is done by visiting the value. When visiting a
+/// `Mappable`, contained entries are passed one-by-one to the visitor by
+/// repeatedly calling [`visit_entry()`].
+///
+/// See [`Visit`] documentation for more details.
+///
+/// [`visit_entry()`]: Visit::visit_entry
+/// [`HashMap`]: std::collections::HashMap
+///
+/// # Implementing
+///
+/// Implementing `Mappable` for a custom map type. The map is represented using
+/// a `Vec` of key/value pairs.
+///
+/// ```
+/// use valuable::{Mappable, Valuable, Value, Visit};
+///
+/// struct MyMap<K, V> {
+/// entries: Vec<(K, V)>,
+/// }
+///
+/// impl<K: Valuable, V: Valuable> Valuable for MyMap<K, V> {
+/// fn as_value(&self) -> Value<'_> {
+/// Value::Mappable(self)
+/// }
+///
+/// fn visit(&self, visit: &mut dyn Visit) {
+/// for (k, v) in &self.entries {
+/// visit.visit_entry(k.as_value(), v.as_value());
+/// }
+/// }
+/// }
+///
+/// impl<K: Valuable, V: Valuable> Mappable for MyMap<K, V> {
+/// fn size_hint(&self) -> (usize, Option<usize>) {
+/// let len = self.entries.len();
+/// (len, Some(len))
+/// }
+/// }
+/// ```
+pub trait Mappable: Valuable {
+ /// Returns the bounds on the remaining length of the `Mappable`.
+ ///
+ /// Specifically, `size_hint()` returns a tuple where the first element is
+ /// the lower bound, and the second element is the upper bound.
+ ///
+ /// The second half of the tuple that is returned is an
+ /// [`Option`]`<`[`usize`]`>`. A [`None`] here means that either there is no
+ /// known upper bound, or the upper bound is larger than [`usize`].
+ ///
+ /// # Implementation notes
+ ///
+ /// It is not enforced that a `Mappable` implementation yields the declared
+ /// number of elements. A buggy implementation may yield less than the lower
+ /// bound or more than the upper bound of elements.
+ ///
+ /// `size_hint()` is primarily intended to be used for optimizations such as
+ /// reserving space for the elements of the `Mappable`, but must not be
+ /// trusted to e.g., omit bounds checks in unsafe code. An incorrect
+ /// implementation of `size_hint()` should not lead to memory safety
+ /// violations.
+ ///
+ /// That said, the implementation should provide a correct estimation,
+ /// because otherwise it would be a violation of the trait's protocol.
+ ///
+ /// [`usize`]: type@usize
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// use valuable::Mappable;
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert("one", 1);
+ /// map.insert("two", 2);
+ /// map.insert("three", 3);
+ ///
+ /// assert_eq!((3, Some(3)), map.size_hint());
+ /// ```
+ fn size_hint(&self) -> (usize, Option<usize>);
+}
+
+macro_rules! deref {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<T: ?Sized + Mappable> Mappable for $ty {
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ T::size_hint(&**self)
+ }
+ }
+ )*
+ };
+}
+
+deref! {
+ &T,
+ &mut T,
+ #[cfg(feature = "alloc")]
+ alloc::boxed::Box<T>,
+ #[cfg(feature = "alloc")]
+ alloc::rc::Rc<T>,
+ #[cfg(not(valuable_no_atomic_cas))]
+ #[cfg(feature = "alloc")]
+ alloc::sync::Arc<T>,
+}
+
+#[cfg(feature = "std")]
+impl<K: Valuable, V: Valuable> Valuable for std::collections::HashMap<K, V> {
+ fn as_value(&self) -> Value<'_> {
+ Value::Mappable(self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ for (key, value) in self.iter() {
+ visit.visit_entry(key.as_value(), value.as_value());
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl<K: Valuable, V: Valuable> Mappable for std::collections::HashMap<K, V> {
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter().size_hint()
+ }
+}
+
+#[cfg(feature = "alloc")]
+impl<K: Valuable, V: Valuable> Valuable for alloc::collections::BTreeMap<K, V> {
+ fn as_value(&self) -> Value<'_> {
+ Value::Mappable(self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ for (key, value) in self.iter() {
+ visit.visit_entry(key.as_value(), value.as_value());
+ }
+ }
+}
+
+#[cfg(feature = "alloc")]
+impl<K: Valuable, V: Valuable> Mappable for alloc::collections::BTreeMap<K, V> {
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter().size_hint()
+ }
+}
+
+impl fmt::Debug for dyn Mappable + '_ {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ struct DebugMappable<'a, 'b> {
+ fmt: fmt::DebugMap<'a, 'b>,
+ }
+
+ impl Visit for DebugMappable<'_, '_> {
+ fn visit_entry(&mut self, key: Value<'_>, value: Value<'_>) {
+ self.fmt.entry(&key, &value);
+ }
+
+ fn visit_value(&mut self, _: Value<'_>) {}
+ }
+
+ let mut debug = DebugMappable {
+ fmt: fmt.debug_map(),
+ };
+ self.visit(&mut debug);
+ debug.fmt.finish()
+ }
+}
diff --git a/vendor/valuable/src/named_values.rs b/vendor/valuable/src/named_values.rs
new file mode 100644
index 000000000..4f436522a
--- /dev/null
+++ b/vendor/valuable/src/named_values.rs
@@ -0,0 +1,222 @@
+use core::iter::{self, FusedIterator};
+
+use crate::field::*;
+use crate::*;
+
+/// Set of values from a `Structable` or `Enumerable` with named fields.
+#[derive(Debug)]
+pub struct NamedValues<'a> {
+ fields: &'a [NamedField<'a>],
+ values: &'a [Value<'a>],
+}
+
+impl<'a> NamedValues<'a> {
+ /// Create a new `NamedValues` instance.
+ ///
+ /// Both `fields` and `values` must be the same length.
+ ///
+ /// # Panics
+ ///
+ /// The method panics if `fields` and `values` are different lengths.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{NamedField, NamedValues, Value};
+ ///
+ /// let fields = [
+ /// NamedField::new("foo"),
+ /// NamedField::new("bar")
+ /// ];
+ /// let values = [
+ /// Value::U32(123),
+ /// Value::U32(456),
+ /// ];
+ ///
+ /// let named_values = NamedValues::new(&fields, &values);
+ ///
+ /// assert_eq!(
+ /// named_values.get(&fields[0]).unwrap().as_u32(),
+ /// Some(123));
+ /// ```
+ pub fn new(fields: &'a [NamedField<'a>], values: &'a [Value<'a>]) -> NamedValues<'a> {
+ assert!(
+ fields.len() == values.len(),
+ "`fields` and `values` must be the same length"
+ );
+ NamedValues { fields, values }
+ }
+
+ /// Get a value using a `NamedField` reference.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{NamedField, NamedValues, Value};
+ ///
+ /// let fields = [
+ /// NamedField::new("foo"),
+ /// NamedField::new("bar")
+ /// ];
+ /// let values = [
+ /// Value::U32(123),
+ /// Value::U32(456),
+ /// ];
+ ///
+ /// let named_values = NamedValues::new(&fields, &values);
+ ///
+ /// assert_eq!(
+ /// named_values.get(&fields[0]).unwrap().as_u32(),
+ /// Some(123));
+ /// ```
+ pub fn get(&self, field: &NamedField<'_>) -> Option<&Value<'_>> {
+ use core::mem;
+
+ let idx = (field as *const _ as usize - &self.fields[0] as *const _ as usize)
+ / mem::size_of::<NamedField<'_>>();
+ self.values.get(idx)
+ }
+
+ /// Get a value using string.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{NamedField, NamedValues, Value};
+ ///
+ /// let fields = [
+ /// NamedField::new("foo"),
+ /// NamedField::new("bar")
+ /// ];
+ /// let values = [
+ /// Value::U32(123),
+ /// Value::U32(456),
+ /// ];
+ ///
+ /// let named_values = NamedValues::new(&fields, &values);
+ ///
+ /// assert_eq!(
+ /// named_values.get_by_name("foo").unwrap().as_u32(),
+ /// Some(123));
+ /// ```
+ pub fn get_by_name(&self, name: impl AsRef<str>) -> Option<&Value<'_>> {
+ let name = name.as_ref();
+
+ for (index, field) in self.fields.iter().enumerate() {
+ if field.name() == name {
+ return Some(&self.values[index]);
+ }
+ }
+
+ None
+ }
+
+ /// Iterate all name-value pairs.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{NamedField, NamedValues, Value};
+ ///
+ /// let fields = [
+ /// NamedField::new("foo"),
+ /// NamedField::new("bar")
+ /// ];
+ /// let values = [
+ /// Value::U32(123),
+ /// Value::U32(456),
+ /// ];
+ ///
+ /// let named_values = NamedValues::new(&fields, &values);
+ ///
+ /// for (field, value) in named_values.iter() {
+ /// println!("{:?}: {:?}", field, value);
+ /// }
+ /// ```
+ pub fn iter<'b>(&'b self) -> Iter<'a, 'b> {
+ Iter {
+ iter: self.fields.iter().enumerate(),
+ values: self.values,
+ }
+ }
+
+ /// Returns the length of fields.
+ pub fn len(&self) -> usize {
+ self.fields.len()
+ }
+
+ /// Returns `true` if fields have a length of 0.
+ pub fn is_empty(&self) -> bool {
+ self.fields.is_empty()
+ }
+}
+
+impl<'a, 'b> IntoIterator for &'b NamedValues<'a> {
+ type Item = (&'b NamedField<'a>, &'b Value<'a>);
+ type IntoIter = Iter<'a, 'b>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.iter()
+ }
+}
+
+/// An iterator of name-value pairs contained by [`NamedValues`].
+///
+/// Instances are created by the [`iter()`][NamedValues::iter] method on
+/// [`NamedValues`]. See its documentation for more.
+///
+/// # Examples
+///
+/// ```
+/// use valuable::{NamedField, NamedValues, Value};
+///
+/// let fields = [
+/// NamedField::new("foo"),
+/// NamedField::new("bar")
+/// ];
+/// let values = [
+/// Value::U32(123),
+/// Value::U32(456),
+/// ];
+///
+/// let named_values = NamedValues::new(&fields, &values);
+///
+/// for (field, value) in named_values.iter() {
+/// println!("{:?}: {:?}", field, value);
+/// }
+/// ```
+#[derive(Debug)]
+pub struct Iter<'a, 'b> {
+ iter: iter::Enumerate<core::slice::Iter<'b, NamedField<'a>>>,
+ values: &'a [Value<'a>],
+}
+
+impl<'a, 'b> Iterator for Iter<'a, 'b> {
+ type Item = (&'b NamedField<'a>, &'b Value<'a>);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter
+ .next()
+ .map(move |(i, field)| (field, &self.values[i]))
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl DoubleEndedIterator for Iter<'_, '_> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.iter
+ .next_back()
+ .map(move |(i, field)| (field, &self.values[i]))
+ }
+}
+
+impl ExactSizeIterator for Iter<'_, '_> {
+ fn len(&self) -> usize {
+ self.iter.len()
+ }
+}
+
+impl FusedIterator for Iter<'_, '_> {}
diff --git a/vendor/valuable/src/slice.rs b/vendor/valuable/src/slice.rs
new file mode 100644
index 000000000..a6ada6e67
--- /dev/null
+++ b/vendor/valuable/src/slice.rs
@@ -0,0 +1,428 @@
+use crate::*;
+
+use core::fmt;
+use core::iter::FusedIterator;
+
+macro_rules! slice {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $variant:ident($ty:ty),
+ )*
+ ) => {
+ /// A slice containing primitive values.
+ ///
+ /// The `Slice` enum is used to pass multiple primitive-values to the
+ /// [visitor][`Visit`]. This is used as an optimization when visiting
+ /// [`Listable`] types to avoid a dynamic dispatch call to [`Visit`] for
+ /// each element in the collection.
+ ///
+ /// `Slice` instances are usually not created explicitly. Instead, they
+ /// are created when calling [`Valuable::visit_slice()`].
+ #[non_exhaustive]
+ pub enum Slice<'a> {
+ $(
+ $(#[$attrs])*
+ $variant(&'a [$ty]),
+ )*
+ }
+
+ /// [`Slice`] iterator
+ ///
+ /// Instances are created by the [`iter()`][Slice::iter] method on
+ /// [`Slice`]. See its documentation for more.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let slice = Slice::U32(&[1, 1, 2, 3, 5]);
+ ///
+ /// for value in slice.iter() {
+ /// println!("{:?}", value);
+ /// }
+ /// ```
+ #[derive(Debug)]
+ pub struct Iter<'a>(IterKind<'a>);
+
+ #[derive(Debug)]
+ enum IterKind<'a> {
+ $(
+ $(#[$attrs])*
+ $variant(core::slice::Iter<'a, $ty>),
+ )*
+ }
+
+ impl<'a> Slice<'a> {
+ /// Returns the number of elements in the slice
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let slice = Slice::U32(&[1, 1, 2, 3, 5]);
+ /// assert_eq!(5, slice.len());
+ /// ```
+ pub fn len(&self) -> usize {
+ #[allow(unused_doc_comments)]
+ match self {
+ $(
+ $(#[$attrs])*
+ Slice::$variant(s) => s.len(),
+ )*
+ }
+ }
+
+
+ /// Returns `true` if the slice is not empty.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let slice = Slice::U32(&[1, 1, 2, 3, 5]);
+ /// assert!(!slice.is_empty());
+ /// ```
+ /// ```
+ /// # use valuable::Slice;
+ /// let slice = Slice::U32(&[]);
+ /// assert!(slice.is_empty());
+ /// ```
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+
+ /// Returns an iterator over the slice.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let slice = Slice::U32(&[1, 1, 2, 3, 5]);
+ ///
+ /// for value in slice.iter() {
+ /// println!("{:?}", value);
+ /// }
+ /// ```
+ pub fn iter(&self) -> Iter<'a> {
+ self.into_iter()
+ }
+ }
+
+ impl<'a> IntoIterator for Slice<'a> {
+ type Item = Value<'a>;
+ type IntoIter = Iter<'a>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ (&self).into_iter()
+ }
+ }
+
+ impl<'a> IntoIterator for &'_ Slice<'a> {
+ type Item = Value<'a>;
+ type IntoIter = Iter<'a>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ #[allow(unused_doc_comments)]
+ Iter(match self {
+ $(
+ $(#[$attrs])*
+ Slice::$variant(s) => IterKind::$variant(s.iter()),
+ )*
+ })
+ }
+ }
+
+ impl fmt::Debug for Slice<'_> {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ use Slice::*;
+
+ let mut d = fmt.debug_list();
+
+ #[allow(unused_doc_comments)]
+ match *self {
+ $(
+ $(#[$attrs])*
+ $variant(v) => d.entries(v),
+ )*
+ };
+
+ d.finish()
+ }
+ }
+
+ impl<'a> Iterator for Iter<'a> {
+ type Item = Value<'a>;
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ use IterKind::*;
+
+ #[allow(unused_doc_comments)]
+ match &self.0 {
+ $(
+ $(#[$attrs])*
+ $variant(v) => v.size_hint(),
+ )*
+ }
+ }
+
+ fn next(&mut self) -> Option<Value<'a>> {
+ use IterKind::*;
+
+ #[allow(unused_doc_comments)]
+ match &mut self.0 {
+ $(
+ $(#[$attrs])*
+ $variant(v) => v.next().map(Valuable::as_value),
+ )*
+ }
+ }
+ }
+
+ impl DoubleEndedIterator for Iter<'_> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ use IterKind::*;
+
+ #[allow(unused_doc_comments)]
+ match &mut self.0 {
+ $(
+ $(#[$attrs])*
+ $variant(v) => v.next_back().map(Valuable::as_value),
+ )*
+ }
+ }
+ }
+
+ impl ExactSizeIterator for Iter<'_> {
+ fn len(&self) -> usize {
+ use IterKind::*;
+
+ #[allow(unused_doc_comments)]
+ match &self.0 {
+ $(
+ $(#[$attrs])*
+ $variant(v) => v.len(),
+ )*
+ }
+ }
+ }
+
+ impl FusedIterator for Iter<'_> {}
+ }
+}
+
+slice! {
+ /// A slice containing `bool` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::Bool(&[true, true, false]);
+ /// ```
+ Bool(bool),
+
+ /// A slice containing `char` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::Char(&['a', 'b', 'c']);
+ /// ```
+ Char(char),
+
+ /// A slice containing `f32` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::F32(&[3.1415, 2.71828]);
+ /// ```
+ F32(f32),
+
+ /// A slice containing `f64` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::F64(&[3.1415, 2.71828]);
+ /// ```
+ F64(f64),
+
+ /// A slice containing `i8` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::I8(&[1, 1, 2, 3, 5]);
+ /// ```
+ I8(i8),
+
+ /// A slice containing `i16` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::I16(&[1, 1, 2, 3, 5]);
+ /// ```
+ I16(i16),
+
+ /// A slice containing `I32` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::I32(&[1, 1, 2, 3, 5]);
+ /// ```
+ I32(i32),
+
+ /// A slice containing `I64` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::I64(&[1, 1, 2, 3, 5]);
+ /// ```
+ I64(i64),
+
+ /// A slice containing `I128` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::I128(&[1, 1, 2, 3, 5]);
+ /// ```
+ I128(i128),
+
+ /// A slice containing `isize` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::Isize(&[1, 1, 2, 3, 5]);
+ /// ```
+ Isize(isize),
+
+ /// A slice containing `str` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::Str(&["foo", "bar", "baz"]);
+ /// ```
+ Str(&'a str),
+
+ /// A slice containing `String` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::String(&["foo".to_string(), "bar".to_string()]);
+ /// ```
+ #[cfg(feature = "alloc")]
+ String(alloc::string::String),
+
+ /// A slice containing `u8` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::U8(&[1, 1, 2, 3, 5]);
+ /// ```
+ U8(u8),
+
+ /// A slice containing `u16` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::U16(&[1, 1, 2, 3, 5]);
+ /// ```
+ U16(u16),
+
+ /// A slice containing `u32` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::U32(&[1, 1, 2, 3, 5]);
+ /// ```
+ U32(u32),
+
+ /// A slice containing `u64` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::U64(&[1, 1, 2, 3, 5]);
+ /// ```
+ U64(u64),
+
+ /// A slice containing `u128` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::U128(&[1, 1, 2, 3, 5]);
+ /// ```
+ U128(u128),
+
+ /// A slice containing `usize` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::Usize(&[1, 1, 2, 3, 5]);
+ /// ```
+ Usize(usize),
+
+ /// A slice containing `()` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::Unit(&[(), (), ()]);
+ /// ```
+ Unit(()),
+}
diff --git a/vendor/valuable/src/structable.rs b/vendor/valuable/src/structable.rs
new file mode 100644
index 000000000..611a7e58b
--- /dev/null
+++ b/vendor/valuable/src/structable.rs
@@ -0,0 +1,496 @@
+use crate::field::*;
+use crate::*;
+
+use core::fmt;
+
+/// A struct-like [`Valuable`] sub-type.
+///
+/// Implemented by [`Valuable`] types that have a struct-like shape. Fields may
+/// be named or unnamed (tuple). Values that implement `Structable` must return
+/// [`Value::Structable`] from their [`Valuable::as_value`] implementation.
+///
+/// # Inspecting
+///
+/// Inspecting fields contained by a `Structable` instance is done by visiting
+/// the struct. When visiting a `Structable`, either the `visit_named_fields()`
+/// or the `visit_unnamed_fields()` methods of `Visit` are called. Each method
+/// may be called multiple times per `Structable`, but the two methods are never
+/// mixed.
+///
+/// ```
+/// use valuable::{NamedValues, Valuable, Value, Visit};
+///
+/// #[derive(Valuable)]
+/// struct MyStruct {
+/// foo: u32,
+/// bar: u32,
+/// }
+///
+/// struct PrintFields;
+///
+/// impl Visit for PrintFields {
+/// fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
+/// for (field, value) in named_values.iter() {
+/// println!("{}: {:?}", field.name(), value);
+/// }
+/// }
+///
+/// fn visit_value(&mut self, value: Value<'_>) {
+/// match value {
+/// Value::Structable(v) => v.visit(self),
+/// _ => {} // do nothing for other types
+/// }
+/// }
+/// }
+///
+/// let my_struct = MyStruct {
+/// foo: 123,
+/// bar: 456,
+/// };
+///
+/// valuable::visit(&my_struct, &mut PrintFields);
+/// ```
+///
+/// If the struct is **statically** defined, then all fields are known ahead of
+/// time and may be accessed via the [`StructDef`] instance returned by
+/// [`definition()`]. [`NamedField`] instances returned by [`definition()`]
+/// maybe used to efficiently extract specific field values.
+///
+/// # Implementing
+///
+/// Implementing `Structable` is usually done by adding `#[derive(Valuable)]` to
+/// a Rust `struct` definition.
+///
+/// ```
+/// use valuable::{Fields, Valuable, Structable, StructDef};
+///
+/// #[derive(Valuable)]
+/// struct MyStruct {
+/// foo: &'static str,
+/// }
+///
+/// let my_struct = MyStruct { foo: "Hello" };
+/// let fields = match my_struct.definition() {
+/// StructDef::Static { name, fields, .. } => {
+/// assert_eq!("MyStruct", name);
+/// fields
+/// }
+/// _ => unreachable!(),
+/// };
+///
+/// match fields {
+/// Fields::Named(named_fields) => {
+/// assert_eq!(1, named_fields.len());
+/// assert_eq!("foo", named_fields[0].name());
+/// }
+/// _ => unreachable!(),
+/// }
+/// ```
+///
+/// [`definition()`]: Structable::definition()
+pub trait Structable: Valuable {
+ /// Returns the struct's definition.
+ ///
+ /// See [`StructDef`] documentation for more details.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Structable, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// struct MyStruct {
+ /// foo: u32,
+ /// }
+ ///
+ /// let my_struct = MyStruct {
+ /// foo: 123,
+ /// };
+ ///
+ /// assert_eq!("MyStruct", my_struct.definition().name());
+ fn definition(&self) -> StructDef<'_>;
+}
+
+/// A struct's name, fields, and other struct-level information.
+///
+/// Returned by [`Structable::definition()`], `StructDef` provides the caller
+/// with information about the struct's definition.
+///
+/// [`Structable::definition()`]: Structable::definition
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum StructDef<'a> {
+ /// The struct is statically-defined, all fields are known ahead of time.
+ ///
+ /// Most `Structable` definitions for Rust struct types will be
+ /// `StructDef::Static`.
+ ///
+ /// # Examples
+ ///
+ /// A statically defined struct
+ ///
+ /// ```
+ /// use valuable::{Fields, Valuable, Structable, StructDef};
+ ///
+ /// #[derive(Valuable)]
+ /// struct MyStruct {
+ /// foo: &'static str,
+ /// }
+ ///
+ /// let my_struct = MyStruct { foo: "Hello" };
+ /// let fields = match my_struct.definition() {
+ /// StructDef::Static { name, fields, ..} => {
+ /// assert_eq!("MyStruct", name);
+ /// fields
+ /// }
+ /// _ => unreachable!(),
+ /// };
+ ///
+ /// match fields {
+ /// Fields::Named(named_fields) => {
+ /// assert_eq!(1, named_fields.len());
+ /// assert_eq!("foo", named_fields[0].name());
+ /// }
+ /// _ => unreachable!(),
+ /// }
+ /// ```
+ #[non_exhaustive]
+ Static {
+ /// The struct's name.
+ name: &'static str,
+
+ /// The struct's fields.
+ fields: Fields<'static>,
+ },
+
+ /// The struct is dynamically-defined, not all fields are known ahead of
+ /// time.
+ ///
+ /// A dynamically-defined struct **could** be represented using
+ /// [`Mappable`], though, using `Structable` offers benefits in a couple of
+ /// cases. For example, when serializing a `Value`, some formats will
+ /// serialize maps and structs differently. In this case, differentiating
+ /// the two is required. There also are times when **some** struct fields
+ /// are known statically, but not all of them (see second example).
+ ///
+ /// # Examples
+ ///
+ /// The struct stores field values in a `HashMap`.
+ ///
+ /// ```
+ /// use valuable::{Fields, NamedField, NamedValues, Structable, StructDef, Value, Valuable, Visit};
+ /// use std::collections::HashMap;
+ ///
+ /// /// A dynamic struct
+ /// struct Dyn {
+ /// // The struct name
+ /// name: String,
+ ///
+ /// // Named values.
+ /// values: HashMap<String, Box<dyn Valuable>>,
+ /// }
+ ///
+ /// impl Valuable for Dyn {
+ /// fn as_value(&self) -> Value<'_> {
+ /// Value::Structable(self)
+ /// }
+ ///
+ /// fn visit(&self, visit: &mut dyn Visit) {
+ /// // This could be optimized to batch some.
+ /// for (field, value) in self.values.iter() {
+ /// visit.visit_named_fields(&NamedValues::new(
+ /// &[NamedField::new(field)],
+ /// &[value.as_value()],
+ /// ));
+ /// }
+ /// }
+ /// }
+ ///
+ /// impl Structable for Dyn {
+ /// fn definition(&self) -> StructDef<'_> {
+ /// StructDef::new_dynamic(&self.name, Fields::Named(&[]))
+ /// }
+ /// }
+ /// ```
+ ///
+ /// Some fields are known statically.
+ ///
+ /// ```
+ /// use valuable::{Fields, NamedField, NamedValues, Structable, StructDef, Value, Valuable, Visit};
+ /// use std::collections::HashMap;
+ ///
+ /// struct HalfStatic {
+ /// foo: u32,
+ /// bar: u32,
+ /// extra_values: HashMap<String, Box<dyn Valuable>>,
+ /// }
+ ///
+ /// impl Valuable for HalfStatic {
+ /// fn as_value(&self) -> Value<'_> {
+ /// Value::Structable(self)
+ /// }
+ ///
+ /// fn visit(&self, visit: &mut dyn Visit) {
+ /// // First, visit static fields
+ /// visit.visit_named_fields(&NamedValues::new(
+ /// FIELDS,
+ /// &[self.foo.as_value(), self.bar.as_value()],
+ /// ));
+ ///
+ /// // This could be optimized to batch some.
+ /// for (field, value) in self.extra_values.iter() {
+ /// visit.visit_named_fields(&NamedValues::new(
+ /// &[NamedField::new(field)],
+ /// &[value.as_value()],
+ /// ));
+ /// }
+ /// }
+ /// }
+ ///
+ /// static FIELDS: &[NamedField<'static>] = &[
+ /// NamedField::new("foo"),
+ /// NamedField::new("bar"),
+ /// ];
+ ///
+ /// impl Structable for HalfStatic {
+ /// fn definition(&self) -> StructDef<'_> {
+ /// // Include known fields.
+ /// StructDef::new_dynamic(
+ /// "HalfStatic",
+ /// Fields::Named(FIELDS))
+ /// }
+ /// }
+ /// ```
+ #[non_exhaustive]
+ Dynamic {
+ /// The struct's name
+ name: &'a str,
+
+ /// The struct's fields.
+ fields: Fields<'a>,
+ },
+}
+
+impl fmt::Debug for dyn Structable + '_ {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let def = self.definition();
+
+ if def.fields().is_named() {
+ struct DebugStruct<'a, 'b> {
+ fmt: fmt::DebugStruct<'a, 'b>,
+ }
+
+ let mut debug = DebugStruct {
+ fmt: fmt.debug_struct(def.name()),
+ };
+
+ impl Visit for DebugStruct<'_, '_> {
+ fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
+ for (field, value) in named_values {
+ self.fmt.field(field.name(), value);
+ }
+ }
+
+ fn visit_value(&mut self, _: Value<'_>) {
+ unreachable!()
+ }
+ }
+
+ self.visit(&mut debug);
+
+ debug.fmt.finish()
+ } else {
+ struct DebugStruct<'a, 'b> {
+ fmt: fmt::DebugTuple<'a, 'b>,
+ }
+
+ let mut debug = DebugStruct {
+ fmt: fmt.debug_tuple(def.name()),
+ };
+
+ impl Visit for DebugStruct<'_, '_> {
+ fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+ for value in values {
+ self.fmt.field(value);
+ }
+ }
+
+ fn visit_value(&mut self, _: Value<'_>) {
+ unreachable!();
+ }
+ }
+
+ self.visit(&mut debug);
+
+ debug.fmt.finish()
+ }
+ }
+}
+
+impl<'a> StructDef<'a> {
+ /// Create a new [`StructDef::Static`] instance.
+ ///
+ /// This should be used when a struct's fields are fixed and known ahead of time.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_static("Foo", Fields::Unnamed(2));
+ /// ```
+ pub const fn new_static(name: &'static str, fields: Fields<'static>) -> StructDef<'a> {
+ StructDef::Static { name, fields }
+ }
+
+ /// Create a new [`StructDef::Dynamic`] instance.
+ ///
+ /// This is used when the struct's fields may vary at runtime.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_dynamic("Foo", Fields::Unnamed(3));
+ /// ```
+ pub const fn new_dynamic(name: &'a str, fields: Fields<'a>) -> StructDef<'a> {
+ StructDef::Dynamic { name, fields }
+ }
+
+ /// Returns the struct's name
+ ///
+ /// # Examples
+ ///
+ /// With a static struct
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_static("Foo", Fields::Unnamed(1));
+ /// assert_eq!("Foo", def.name());
+ /// ```
+ ///
+ /// With a dynamic struct
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_dynamic("Foo", Fields::Unnamed(2));
+ /// assert_eq!("Foo", def.name());
+ /// ```
+ pub const fn name(&self) -> &'a str {
+ match self {
+ StructDef::Static { name, .. } => name,
+ StructDef::Dynamic { name, .. } => name,
+ }
+ }
+
+ /// Returns the struct's fields
+ ///
+ /// # Examples
+ ///
+ /// With a static struct
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_static("Foo", Fields::Unnamed(3));
+ /// assert!(matches!(def.fields(), Fields::Unnamed(_)));
+ /// ```
+ ///
+ /// With a dynamic struct
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_dynamic("Foo", Fields::Unnamed(1));
+ /// assert!(matches!(def.fields(), Fields::Unnamed(_)));
+ /// ```
+ pub const fn fields(&self) -> &Fields<'a> {
+ match self {
+ StructDef::Static { fields, .. } => fields,
+ StructDef::Dynamic { fields, .. } => fields,
+ }
+ }
+
+ /// Returns `true` if the struct is [statically defined](StructDef::Static).
+ ///
+ /// # Examples
+ ///
+ /// With a static struct
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_static("Foo", Fields::Unnamed(2));
+ /// assert!(def.is_static());
+ /// ```
+ ///
+ /// With a dynamic struct
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_dynamic("Foo", Fields::Unnamed(4));
+ /// assert!(!def.is_static());
+ /// ```
+ pub const fn is_static(&self) -> bool {
+ matches!(self, StructDef::Static { .. })
+ }
+
+ /// Returns `true` if the struct is [dynamically defined](StructDef::Dynamic).
+ ///
+ /// # Examples
+ ///
+ /// With a static struct
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_static("Foo", Fields::Unnamed(1));
+ /// assert!(!def.is_dynamic());
+ /// ```
+ ///
+ /// With a dynamic struct
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_dynamic("Foo", Fields::Unnamed(1));
+ /// assert!(def.is_dynamic());
+ /// ```
+ pub const fn is_dynamic(&self) -> bool {
+ matches!(self, StructDef::Dynamic { .. })
+ }
+}
+
+macro_rules! deref {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<T: ?Sized + Structable> Structable for $ty {
+ fn definition(&self) -> StructDef<'_> {
+ T::definition(&**self)
+ }
+ }
+ )*
+ };
+}
+
+deref! {
+ &T,
+ &mut T,
+ #[cfg(feature = "alloc")]
+ alloc::boxed::Box<T>,
+ #[cfg(feature = "alloc")]
+ alloc::rc::Rc<T>,
+ #[cfg(not(valuable_no_atomic_cas))]
+ #[cfg(feature = "alloc")]
+ alloc::sync::Arc<T>,
+}
diff --git a/vendor/valuable/src/tuplable.rs b/vendor/valuable/src/tuplable.rs
new file mode 100644
index 000000000..8c7169ff2
--- /dev/null
+++ b/vendor/valuable/src/tuplable.rs
@@ -0,0 +1,339 @@
+use crate::{Valuable, Value, Visit};
+
+use core::fmt;
+
+/// A tuple-like [`Valuable`] sub-type.
+///
+/// Implemented by [`Valuable`] types that have a tuple-like shape. Fields are
+/// always unnamed. Values that implement `Tuplable` must return
+/// [`Value::Tuplable`] from their [`Valuable::as_value`] implementation.
+///
+/// It is uncommon for users to implement this type as the crate provides
+/// implementations of `Tuplable` for Rust tuples.
+///
+/// # Inspecting
+///
+/// Inspecting fields contained by a `Tuplable` instance is done by visiting the
+/// tuple. When visiting a `Tuple`, the `visit_unnamed_fields()` method is
+/// called. When the tuple is statically defined, `visit_unnamed_fields()` is
+/// called once with the values of all the fields. A dynamic tuple
+/// implementation may call `visit_unnamed_fields()` multiple times.
+pub trait Tuplable: Valuable {
+ /// Returns the tuple's definition.
+ ///
+ /// See [`TupleDef`] documentation for more details.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Tuplable, TupleDef};
+ ///
+ /// let tuple = (123, "hello");
+ ///
+ /// if let TupleDef::Static { fields, .. } = tuple.definition() {
+ /// assert_eq!(2, fields);
+ /// }
+ /// ```
+ fn definition(&self) -> TupleDef;
+}
+
+/// The number of fields and other tuple-level information.
+///
+/// Returned by [`Tuplable::definition()`], `TupleDef` provides the caller with
+/// information about the tuple's definition.
+///
+/// This includes the number of fields contained by the tuple.
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum TupleDef {
+ /// The tuple is statically-defined, all fields are known ahead of time.
+ ///
+ /// Static tuple implementations are provided by the crate.
+ ///
+ /// # Examples
+ ///
+ /// A statically defined tuple.
+ ///
+ /// ```
+ /// use valuable::{Tuplable, TupleDef};
+ ///
+ /// let tuple = (123, "hello");
+ ///
+ /// match tuple.definition() {
+ /// TupleDef::Static { fields, .. } => {
+ /// assert_eq!(2, fields);
+ /// }
+ /// _ => unreachable!(),
+ /// };
+ /// ```
+ #[non_exhaustive]
+ Static {
+ /// The number of fields contained by the tuple.
+ fields: usize,
+ },
+ /// The tuple is dynamically-defined, not all fields are known ahead of
+ /// time.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Tuplable, TupleDef, Valuable, Value, Visit};
+ ///
+ /// struct MyTuple;
+ ///
+ /// impl Valuable for MyTuple {
+ /// fn as_value(&self) -> Value<'_> {
+ /// Value::Tuplable(self)
+ /// }
+ ///
+ /// fn visit(&self, visit: &mut dyn Visit) {
+ /// visit.visit_unnamed_fields(&[Value::I32(123)]);
+ /// visit.visit_unnamed_fields(&[Value::String("hello world")]);
+ /// }
+ /// }
+ ///
+ /// impl Tuplable for MyTuple {
+ /// fn definition(&self) -> TupleDef {
+ /// TupleDef::new_dynamic((1, Some(3)))
+ /// }
+ /// }
+ /// ```
+ #[non_exhaustive]
+ Dynamic {
+ /// Returns the bounds on the number of tuple fields.
+ ///
+ /// Specifically, the first element is the lower bound, and the second
+ /// element is the upper bound.
+ fields: (usize, Option<usize>),
+ },
+}
+
+macro_rules! deref {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<T: ?Sized + Tuplable> Tuplable for $ty {
+ fn definition(&self) -> TupleDef {
+ T::definition(&**self)
+ }
+ }
+ )*
+ };
+}
+
+deref! {
+ &T,
+ &mut T,
+ #[cfg(feature = "alloc")]
+ alloc::boxed::Box<T>,
+ #[cfg(feature = "alloc")]
+ alloc::rc::Rc<T>,
+ #[cfg(not(valuable_no_atomic_cas))]
+ #[cfg(feature = "alloc")]
+ alloc::sync::Arc<T>,
+}
+
+impl Tuplable for () {
+ fn definition(&self) -> TupleDef {
+ TupleDef::Static { fields: 0 }
+ }
+}
+
+macro_rules! tuple_impls {
+ (
+ $( $len:expr => ( $($n:tt $name:ident)+ ) )+
+ ) => {
+ $(
+ impl<$($name),+> Valuable for ($($name,)+)
+ where
+ $($name: Valuable,)+
+ {
+ fn as_value(&self) -> Value<'_> {
+ Value::Tuplable(self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_unnamed_fields(&[
+ $(
+ self.$n.as_value(),
+ )+
+ ]);
+ }
+ }
+
+ impl<$($name),+> Tuplable for ($($name,)+)
+ where
+ $($name: Valuable,)+
+ {
+ fn definition(&self) -> TupleDef {
+ TupleDef::Static { fields: $len }
+ }
+ }
+ )+
+ }
+}
+
+tuple_impls! {
+ 1 => (0 T0)
+ 2 => (0 T0 1 T1)
+ 3 => (0 T0 1 T1 2 T2)
+ 4 => (0 T0 1 T1 2 T2 3 T3)
+ 5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
+ 6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
+ 7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
+ 8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
+ 9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
+ 10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
+ 11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
+ 12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
+ 13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
+ 14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
+ 15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
+ 16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
+}
+
+impl fmt::Debug for dyn Tuplable + '_ {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ if self.definition().is_unit() {
+ ().fmt(fmt)
+ } else {
+ struct DebugTuple<'a, 'b> {
+ fmt: fmt::DebugTuple<'a, 'b>,
+ }
+
+ impl Visit for DebugTuple<'_, '_> {
+ fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+ for value in values {
+ self.fmt.field(value);
+ }
+ }
+
+ fn visit_value(&mut self, _: Value<'_>) {
+ unimplemented!()
+ }
+ }
+
+ let mut debug = DebugTuple {
+ fmt: fmt.debug_tuple(""),
+ };
+
+ self.visit(&mut debug);
+ debug.fmt.finish()
+ }
+ }
+}
+
+impl TupleDef {
+ /// Create a new [`TupleDef::Static`] instance
+ ///
+ /// This should be used when the tuple's fields are fixed and known ahead of time.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::TupleDef;
+ ///
+ /// let def = TupleDef::new_static(2);
+ /// ```
+ pub const fn new_static(fields: usize) -> TupleDef {
+ TupleDef::Static { fields }
+ }
+
+ /// Create a new [`TupleDef::Dynamic`] instance.
+ ///
+ /// This is used when the tuple's fields may vary at runtime.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::TupleDef;
+ ///
+ /// let def = TupleDef::new_dynamic((2, Some(10)));
+ /// ```
+ pub const fn new_dynamic(fields: (usize, Option<usize>)) -> TupleDef {
+ TupleDef::Dynamic { fields }
+ }
+
+ /// Returns `true` if `self` represents the [unit][primitive@unit] tuple.
+ ///
+ /// # Examples
+ ///
+ /// With the unit tuple
+ ///
+ /// ```
+ /// use valuable::Tuplable;
+ ///
+ /// let tuple: &dyn Tuplable = &();
+ /// assert!(tuple.definition().is_unit());
+ /// ```
+ ///
+ /// When not the unit tuple.
+ ///
+ /// ```
+ /// use valuable::Tuplable;
+ ///
+ /// let tuple: &dyn Tuplable = &(123,456);
+ /// assert!(!tuple.definition().is_unit());
+ /// ```
+ pub fn is_unit(&self) -> bool {
+ match *self {
+ TupleDef::Static { fields } => fields == 0,
+ TupleDef::Dynamic { fields } => fields == (0, Some(0)),
+ }
+ }
+
+ /// Returns `true` if the tuple is [statically defined](TupleDef::Static).
+ ///
+ /// # Examples
+ ///
+ /// With a static tuple
+ ///
+ /// ```
+ /// use valuable::TupleDef;
+ ///
+ /// let def = TupleDef::new_static(2);
+ /// assert!(def.is_static());
+ /// ```
+ ///
+ /// With a dynamic tuple
+ ///
+ /// ```
+ /// use valuable::TupleDef;
+ ///
+ /// let def = TupleDef::new_dynamic((2, None));
+ /// assert!(!def.is_static());
+ /// ```
+ pub fn is_static(&self) -> bool {
+ matches!(self, TupleDef::Static { .. })
+ }
+
+ /// Returns `true` if the tuple is [dynamically defined](TupleDef::Dynamic).
+ ///
+ /// # Examples
+ ///
+ /// With a static tuple
+ ///
+ /// ```
+ /// use valuable::TupleDef;
+ ///
+ /// let def = TupleDef::new_static(2);
+ /// assert!(!def.is_dynamic());
+ /// ```
+ ///
+ /// With a dynamic tuple
+ ///
+ /// ```
+ /// use valuable::TupleDef;
+ ///
+ /// let def = TupleDef::new_dynamic((2, None));
+ /// assert!(def.is_dynamic());
+ /// ```
+ pub fn is_dynamic(&self) -> bool {
+ matches!(self, TupleDef::Dynamic { .. })
+ }
+}
diff --git a/vendor/valuable/src/valuable.rs b/vendor/valuable/src/valuable.rs
new file mode 100644
index 000000000..e8fa5ddcf
--- /dev/null
+++ b/vendor/valuable/src/valuable.rs
@@ -0,0 +1,339 @@
+use crate::{Slice, Value, Visit};
+
+use core::fmt;
+use core::num::Wrapping;
+
+/// A type that can be converted to a [`Value`].
+///
+/// `Valuable` types are inspected by defining a [`Visit`] implementation and
+/// using it when calling [`Valuable::visit`]. See [`Visit`] documentation for
+/// more details.
+///
+/// The `Valuable` procedural macro makes implementing `Valuable` easy. Users
+/// can add add [`#[derive(Valuable)]`][macro] to their types.
+///
+/// `Valuable` provides implementations for many Rust primitives and standard
+/// library types.
+///
+/// Types implementing `Valuable` may also implement one of the more specific
+/// traits: [`Structable`], [`Enumerable`], [`Listable`], and [`Mappable`]. These traits
+/// should be implemented when the type is a nested container of other `Valuable` types.
+///
+/// [`Value`]: Value
+/// [`Visit`]: Visit
+/// [`Valuable::visit`]: Valuable::visit
+/// [`Structable`]: crate::Structable
+/// [`Enumerable`]: crate::Enumerable
+/// [`Listable`]: crate::Listable
+/// [`Mappable`]: crate::Mappable
+/// [macro]: macro@crate::Valuable
+pub trait Valuable {
+ /// Converts self into a [`Value`] instance.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Valuable;
+ ///
+ /// let _ = "hello".as_value();
+ /// ```
+ fn as_value(&self) -> Value<'_>;
+
+ /// Calls the relevant method on [`Visit`] to extract data from `self`.
+ ///
+ /// This method is used to extract type-specific data from the value and is
+ /// intended to be an implementation detail. For example, `Vec` implements
+ /// `visit` by calling [`visit_value()`] on each of its elements. Structs
+ /// implement `visit` by calling [`visit_named_fields()`] or
+ /// [`visit_unnamed_fields()`].
+ ///
+ /// Usually, users will call the [`visit`] function instead.
+ ///
+ /// [`Visit`]: Visit
+ /// [`visit`]: visit()
+ /// [`visit_value()`]: Visit::visit_value()
+ /// [`visit_named_fields()`]: Visit::visit_named_fields()
+ /// [`visit_unnamed_fields()`]: Visit::visit_unnamed_fields()
+ fn visit(&self, visit: &mut dyn Visit);
+
+ /// Calls [`Visit::visit_primitive_slice()`] with `self`.
+ ///
+ /// This method is an implementation detail used to optimize visiting
+ /// primitive slices.
+ ///
+ /// [`Visit::visit_primitive_slice()`]: Visit::visit_primitive_slice
+ fn visit_slice(slice: &[Self], visit: &mut dyn Visit)
+ where
+ Self: Sized,
+ {
+ for item in slice {
+ visit.visit_value(item.as_value());
+ }
+ }
+}
+
+macro_rules! deref {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<T: ?Sized + Valuable> Valuable for $ty {
+ fn as_value(&self) -> Value<'_> {
+ T::as_value(&**self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ T::visit(&**self, visit);
+ }
+ }
+ )*
+ };
+}
+
+deref! {
+ &T,
+ &mut T,
+ #[cfg(feature = "alloc")]
+ alloc::boxed::Box<T>,
+ #[cfg(feature = "alloc")]
+ alloc::rc::Rc<T>,
+ #[cfg(not(valuable_no_atomic_cas))]
+ #[cfg(feature = "alloc")]
+ alloc::sync::Arc<T>,
+}
+
+macro_rules! valuable {
+ (
+ $(
+ $variant:ident($ty:ty),
+ )*
+ ) => {
+ $(
+ impl Valuable for $ty {
+ fn as_value(&self) -> Value<'_> {
+ Value::$variant(*self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(self.as_value());
+ }
+
+ fn visit_slice(slice: &[Self], visit: &mut dyn Visit)
+ where
+ Self: Sized,
+ {
+ visit.visit_primitive_slice(Slice::$variant(slice));
+ }
+ }
+ )*
+ };
+}
+
+valuable! {
+ Bool(bool),
+ Char(char),
+ F32(f32),
+ F64(f64),
+ I8(i8),
+ I16(i16),
+ I32(i32),
+ I64(i64),
+ I128(i128),
+ Isize(isize),
+ U8(u8),
+ U16(u16),
+ U32(u32),
+ U64(u64),
+ U128(u128),
+ Usize(usize),
+}
+
+macro_rules! nonzero {
+ (
+ $(
+ $variant:ident($ty:ident),
+ )*
+ ) => {
+ $(
+ impl Valuable for core::num::$ty {
+ fn as_value(&self) -> Value<'_> {
+ Value::$variant(self.get())
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(self.as_value());
+ }
+ }
+ )*
+ };
+}
+
+nonzero! {
+ I8(NonZeroI8),
+ I16(NonZeroI16),
+ I32(NonZeroI32),
+ I64(NonZeroI64),
+ I128(NonZeroI128),
+ Isize(NonZeroIsize),
+ U8(NonZeroU8),
+ U16(NonZeroU16),
+ U32(NonZeroU32),
+ U64(NonZeroU64),
+ U128(NonZeroU128),
+ Usize(NonZeroUsize),
+}
+
+#[cfg(not(valuable_no_atomic))]
+macro_rules! atomic {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $variant:ident($ty:ident),
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl Valuable for core::sync::atomic::$ty {
+ fn as_value(&self) -> Value<'_> {
+ // Use SeqCst to match Debug and serde which use SeqCst.
+ // https://github.com/rust-lang/rust/blob/1.52.1/library/core/src/sync/atomic.rs#L1361-L1366
+ // https://github.com/serde-rs/serde/issues/1496
+ Value::$variant(self.load(core::sync::atomic::Ordering::SeqCst))
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(self.as_value());
+ }
+ }
+ )*
+ };
+}
+
+#[cfg(not(valuable_no_atomic))]
+atomic! {
+ Bool(AtomicBool),
+ I8(AtomicI8),
+ I16(AtomicI16),
+ I32(AtomicI32),
+ #[cfg(not(valuable_no_atomic_64))]
+ I64(AtomicI64),
+ Isize(AtomicIsize),
+ U8(AtomicU8),
+ U16(AtomicU16),
+ U32(AtomicU32),
+ #[cfg(not(valuable_no_atomic_64))]
+ U64(AtomicU64),
+ Usize(AtomicUsize),
+}
+
+impl<T: Valuable> Valuable for Wrapping<T> {
+ fn as_value(&self) -> Value<'_> {
+ self.0.as_value()
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ self.0.visit(visit);
+ }
+}
+
+impl Valuable for () {
+ fn as_value(&self) -> Value<'_> {
+ Value::Tuplable(self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_unnamed_fields(&[]);
+ }
+}
+
+impl<T: Valuable> Valuable for Option<T> {
+ fn as_value(&self) -> Value<'_> {
+ match self {
+ Some(v) => v.as_value(),
+ None => Value::Unit,
+ }
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(self.as_value());
+ }
+}
+
+impl Valuable for &'_ str {
+ fn as_value(&self) -> Value<'_> {
+ Value::String(self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(Value::String(self));
+ }
+
+ fn visit_slice(slice: &[Self], visit: &mut dyn Visit)
+ where
+ Self: Sized,
+ {
+ visit.visit_primitive_slice(Slice::Str(slice));
+ }
+}
+
+#[cfg(feature = "alloc")]
+impl Valuable for alloc::string::String {
+ fn as_value(&self) -> Value<'_> {
+ Value::String(&self[..])
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(Value::String(self));
+ }
+
+ fn visit_slice(slice: &[Self], visit: &mut dyn Visit)
+ where
+ Self: Sized,
+ {
+ visit.visit_primitive_slice(Slice::String(slice));
+ }
+}
+
+#[cfg(feature = "std")]
+impl Valuable for &std::path::Path {
+ fn as_value(&self) -> Value<'_> {
+ Value::Path(self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(Value::Path(self));
+ }
+}
+
+#[cfg(feature = "std")]
+impl Valuable for std::path::PathBuf {
+ fn as_value(&self) -> Value<'_> {
+ Value::Path(self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(Value::Path(self));
+ }
+}
+
+#[cfg(feature = "std")]
+impl Valuable for dyn std::error::Error + 'static {
+ fn as_value(&self) -> Value<'_> {
+ Value::Error(self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(self.as_value());
+ }
+}
+
+impl fmt::Debug for dyn Valuable + '_ {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let value = self.as_value();
+ value.fmt(fmt)
+ }
+}
diff --git a/vendor/valuable/src/value.rs b/vendor/valuable/src/value.rs
new file mode 100644
index 000000000..2db9cd10a
--- /dev/null
+++ b/vendor/valuable/src/value.rs
@@ -0,0 +1,877 @@
+use crate::{Enumerable, Listable, Mappable, Structable, Tuplable, Valuable, Visit};
+
+use core::fmt;
+
+macro_rules! value {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $variant:ident($ty:ty),
+ )*
+ ) => {
+ /// Any Rust value
+ ///
+ /// The `Value` enum is used to pass single values to the
+ /// [visitor][`Visit`]. Primitive types are enumerated and other types
+ /// are represented at trait objects.
+ ///
+ /// Values are converted to `Value` instances using
+ /// [`Valuable::as_value()`].
+ ///
+ /// # Examples
+ ///
+ /// Convert a primitive type
+ ///
+ /// ```
+ /// use valuable::{Value, Valuable};
+ ///
+ /// let num = 123;
+ /// let val = num.as_value();
+ ///
+ /// assert!(matches!(val, Value::I32(v) if v == 123));
+ /// ```
+ ///
+ /// Converting a struct
+ ///
+ /// ```
+ /// use valuable::{Value, Valuable};
+ ///
+ /// #[derive(Valuable, Debug)]
+ /// struct HelloWorld {
+ /// message: String,
+ /// }
+ ///
+ /// let hello = HelloWorld {
+ /// message: "greetings".to_string(),
+ /// };
+ ///
+ /// let val = hello.as_value();
+ ///
+ /// assert!(matches!(val, Value::Structable(_v)));
+ ///
+ /// // The Value `Debug` output matches the struct's
+ /// assert_eq!(
+ /// format!("{:?}", val),
+ /// format!("{:?}", hello),
+ /// );
+ /// ```
+ ///
+ /// [visitor]: Visit
+ #[non_exhaustive]
+ #[derive(Clone, Copy)]
+ pub enum Value<'a> {
+ $(
+ $(#[$attrs])*
+ $variant($ty),
+ )*
+
+ /// A Rust `()` or `None` value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::Unit;
+ /// ```
+ Unit,
+ }
+
+ $(
+ $(#[$attrs])*
+ impl<'a> From<$ty> for Value<'a> {
+ fn from(src: $ty) -> Value<'a> {
+ Value::$variant(src)
+ }
+ }
+ )*
+
+ impl<'a> From<()> for Value<'a> {
+ fn from(_: ()) -> Value<'a> {
+ Value::Tuplable(&())
+ }
+ }
+
+ impl fmt::Debug for Value<'_> {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ use Value::*;
+
+ // Doc comments are expanded into the branch arms, which results
+ // in a warning. It isn't a big deal, so silence it.
+ #[allow(unused_doc_comments)]
+ match self {
+ $(
+ $(#[$attrs])*
+ $variant(v) => fmt::Debug::fmt(v, fmt),
+ )*
+ Unit => ().fmt(fmt),
+ }
+ }
+ }
+ }
+}
+
+value! {
+ /// A Rust `bool` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::Bool(true);
+ /// ```
+ Bool(bool),
+
+ /// A Rust `char` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::Char('h');
+ /// ```
+ Char(char),
+
+ /// A Rust `f32` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::F32(3.1415);
+ /// ```
+ F32(f32),
+
+ /// A Rust `f64` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::F64(3.1415);
+ /// ```
+ F64(f64),
+
+ /// A Rust `i8` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::I8(42);
+ /// ```
+ I8(i8),
+
+ /// A Rust `i16` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::I16(42);
+ /// ```
+ I16(i16),
+
+ /// A Rust `i32` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::I32(42);
+ /// ```
+ I32(i32),
+
+ /// A Rust `i64` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::I64(42);
+ /// ```
+ I64(i64),
+
+ /// A Rust `i128` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::I128(42);
+ /// ```
+ I128(i128),
+
+ /// A Rust `isize` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::Isize(42);
+ /// ```
+ Isize(isize),
+
+ /// A Rust `&str` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::String("hello");
+ /// ```
+ String(&'a str),
+
+ /// A Rust `u8` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::U8(42);
+ /// ```
+ U8(u8),
+
+ /// A Rust `u16` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::U16(42);
+ /// ```
+ U16(u16),
+
+ /// A Rust `u32` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::U32(42);
+ /// ```
+ U32(u32),
+
+ /// A Rust `u64` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::U64(42);
+ /// ```
+ U64(u64),
+
+ /// A Rust `u128` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::U128(42);
+ /// ```
+ U128(u128),
+
+ /// A Rust `usize` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::Usize(42);
+ /// ```
+ Usize(usize),
+
+ /// A Rust `&Path` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ /// use std::path::Path;
+ ///
+ /// let path = Path::new("a.txt");
+ /// let v = Value::Path(path);
+ /// ```
+ #[cfg(feature = "std")]
+ Path(&'a std::path::Path),
+
+ /// A Rust error value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ /// use std::io;
+ ///
+ /// let err: io::Error = io::ErrorKind::Other.into();
+ /// let v = Value::Error(&err);
+ /// ```
+ #[cfg(feature = "std")]
+ Error(&'a (dyn std::error::Error +'static)),
+
+ /// A Rust list value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let vals = vec![1, 2, 3, 4, 5];
+ /// let v = Value::Listable(&vals);
+ /// ```
+ Listable(&'a dyn Listable),
+
+ /// A Rust map value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert("foo", 1);
+ /// map.insert("bar", 2);
+ ///
+ /// let v = Value::Mappable(&map);
+ /// ```
+ Mappable(&'a dyn Mappable),
+
+ /// A Rust struct value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Value, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// struct MyStruct {
+ /// field: u32,
+ /// }
+ ///
+ /// let my_struct = MyStruct {
+ /// field: 123,
+ /// };
+ ///
+ /// let v = Value::Structable(&my_struct);
+ /// ```
+ Structable(&'a dyn Structable),
+
+ /// A Rust enum value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Value, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// enum MyEnum {
+ /// Foo,
+ /// Bar,
+ /// }
+ ///
+ /// let my_enum = MyEnum::Foo;
+ /// let v = Value::Enumerable(&my_enum);
+ /// ```
+ Enumerable(&'a dyn Enumerable),
+
+ /// A tuple value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Value, Valuable};
+ ///
+ /// let my_tuple = (123, 456);
+ /// let v = Value::Tuplable(&my_tuple);
+ /// ```
+ Tuplable(&'a dyn Tuplable),
+}
+
+impl Valuable for Value<'_> {
+ fn as_value(&self) -> Value<'_> {
+ *self
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(*self);
+ }
+}
+
+impl Default for Value<'_> {
+ fn default() -> Self {
+ Value::Unit
+ }
+}
+
+macro_rules! convert {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $ty:ty => $as:ident,
+ )*
+ ) => {
+ impl<'a> Value<'a> {
+ /// Return a `bool` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::Bool(true).as_bool(), Some(true));
+ /// assert_eq!(Value::Char('c').as_bool(), None);
+ /// ```
+ pub fn as_bool(&self) -> Option<bool> {
+ match *self {
+ Value::Bool(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `char` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::Char('c').as_char(), Some('c'));
+ /// assert_eq!(Value::Bool(true).as_char(), None);
+ /// ```
+ pub fn as_char(&self) -> Option<char> {
+ match *self {
+ Value::Char(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `f32` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::F32(3.1415).as_f32(), Some(3.1415));
+ /// assert_eq!(Value::Bool(true).as_f32(), None);
+ /// ```
+ pub fn as_f32(&self) -> Option<f32> {
+ match *self {
+ Value::F32(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `f64` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::F64(3.1415).as_f64(), Some(3.1415));
+ /// assert_eq!(Value::Bool(true).as_f64(), None);
+ /// ```
+ pub fn as_f64(&self) -> Option<f64> {
+ match *self {
+ Value::F64(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ $(
+ $(#[$attrs])*
+ pub fn $as(&self) -> Option<$ty> {
+ use Value::*;
+ use core::convert::TryInto;
+
+ match *self {
+ I8(v) => v.try_into().ok(),
+ I16(v) => v.try_into().ok(),
+ I32(v) => v.try_into().ok(),
+ I64(v) => v.try_into().ok(),
+ I128(v) => v.try_into().ok(),
+ Isize(v) => v.try_into().ok(),
+ U8(v) => v.try_into().ok(),
+ U16(v) => v.try_into().ok(),
+ U32(v) => v.try_into().ok(),
+ U64(v) => v.try_into().ok(),
+ U128(v) => v.try_into().ok(),
+ Usize(v) => v.try_into().ok(),
+ _ => None,
+ }
+ }
+ )*
+
+ /// Return a `&str` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::String("hello").as_str(), Some("hello"));
+ /// assert_eq!(Value::Bool(true).as_str(), None);
+ /// ```
+ pub fn as_str(&self) -> Option<&str> {
+ match *self {
+ Value::String(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `&Path` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ /// use std::path::Path;
+ ///
+ /// let path = Path::new("a.txt");
+ ///
+ /// assert!(Value::Path(path).as_path().is_some());
+ /// assert!(Value::Bool(true).as_path().is_none());
+ /// ```
+ #[cfg(feature = "std")]
+ pub fn as_path(&self) -> Option<&std::path::Path> {
+ match *self {
+ Value::Path(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `&dyn Error` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ /// use std::io;
+ ///
+ /// let err: io::Error = io::ErrorKind::Other.into();
+ ///
+ /// assert!(Value::Error(&err).as_error().is_some());
+ /// assert!(Value::Bool(true).as_error().is_none());
+ /// ```
+ #[cfg(feature = "std")]
+ pub fn as_error(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ match *self {
+ Value::Error(v) => Some(v),
+ _ => None,
+ }
+ }
+
+
+ /// Return a `&dyn Listable` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let list = vec![1, 2, 3, 4];
+ ///
+ /// assert!(Value::Listable(&list).as_listable().is_some());
+ /// assert!(Value::Bool(true).as_listable().is_none());
+ /// ```
+ pub fn as_listable(&self) -> Option<&dyn Listable> {
+ match *self {
+ Value::Listable(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `&dyn Mappable` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert("foo", 123);
+ /// map.insert("bar", 456);
+ ///
+ /// assert!(Value::Mappable(&map).as_mappable().is_some());
+ /// assert!(Value::Bool(true).as_mappable().is_none());
+ /// ```
+ pub fn as_mappable(&self) -> Option<&dyn Mappable> {
+ match *self {
+ Value::Mappable(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `&dyn Structable` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Value, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// struct Hello {
+ /// message: &'static str,
+ /// }
+ ///
+ /// let hello = Hello { message: "Hello world" };
+ ///
+ /// assert!(Value::Structable(&hello).as_structable().is_some());
+ /// assert!(Value::Bool(true).as_structable().is_none());
+ /// ```
+ pub fn as_structable(&self) -> Option<&dyn Structable> {
+ match *self {
+ Value::Structable(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `&dyn Enumerable` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Value, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// enum Greet {
+ /// Hello,
+ /// World,
+ /// }
+ ///
+ /// let greet = Greet::Hello;
+ ///
+ /// assert!(Value::Enumerable(&greet).as_enumerable().is_some());
+ /// assert!(Value::Bool(true).as_enumerable().is_none());
+ /// ```
+ pub fn as_enumerable(&self) -> Option<&dyn Enumerable> {
+ match *self {
+ Value::Enumerable(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `&dyn Tuplable` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let my_tuple = (123, 456);
+ ///
+ /// assert!(Value::Tuplable(&my_tuple).as_tuplable().is_some());
+ /// assert!(Value::Bool(true).as_tuplable().is_none());
+ /// ```
+ pub fn as_tuplable(&self) -> Option<&dyn Tuplable> {
+ match *self {
+ Value::Tuplable(v) => Some(v),
+ _ => None,
+ }
+ }
+ }
+ }
+}
+
+convert! {
+ /// Return a `i8` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::I8(42).as_i8(), Some(42));
+ /// assert_eq!(Value::I32(42).as_i8(), Some(42));
+ ///
+ /// assert_eq!(Value::I64(i64::MAX).as_i8(), None);
+ /// assert_eq!(Value::Bool(true).as_i8(), None);
+ /// ```
+ i8 => as_i8,
+
+ /// Return a `i16` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::I16(42).as_i16(), Some(42));
+ /// assert_eq!(Value::I32(42).as_i16(), Some(42));
+ ///
+ /// assert_eq!(Value::I64(i64::MAX).as_i16(), None);
+ /// assert_eq!(Value::Bool(true).as_i16(), None);
+ /// ```
+ i16 => as_i16,
+
+ /// Return a `i32` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::I32(42).as_i32(), Some(42));
+ /// assert_eq!(Value::I64(42).as_i32(), Some(42));
+ ///
+ /// assert_eq!(Value::I64(i64::MAX).as_i32(), None);
+ /// assert_eq!(Value::Bool(true).as_i32(), None);
+ /// ```
+ i32 => as_i32,
+
+ /// Return a `i64` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::I64(42).as_i64(), Some(42));
+ /// assert_eq!(Value::I128(42).as_i64(), Some(42));
+ ///
+ /// assert_eq!(Value::I128(i128::MAX).as_i64(), None);
+ /// assert_eq!(Value::Bool(true).as_i64(), None);
+ /// ```
+ i64 => as_i64,
+
+ /// Return a `i128` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::I128(42).as_i128(), Some(42));
+ /// assert_eq!(Value::U128(42).as_i128(), Some(42));
+ ///
+ /// assert_eq!(Value::U128(u128::MAX).as_i128(), None);
+ /// assert_eq!(Value::Bool(true).as_i128(), None);
+ /// ```
+ i128 => as_i128,
+
+ /// Return a `isize` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::Isize(42).as_isize(), Some(42));
+ /// assert_eq!(Value::Usize(42).as_isize(), Some(42));
+ ///
+ /// assert_eq!(Value::Usize(usize::MAX).as_isize(), None);
+ /// assert_eq!(Value::Bool(true).as_isize(), None);
+ /// ```
+ isize => as_isize,
+
+ /// Return a `u8` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::U8(42).as_u8(), Some(42));
+ /// assert_eq!(Value::U32(42).as_u8(), Some(42));
+ ///
+ /// assert_eq!(Value::U32(u32::MAX).as_u8(), None);
+ /// assert_eq!(Value::Bool(true).as_u8(), None);
+ /// ```
+ u8 => as_u8,
+
+ /// Return a `u16` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::U16(42).as_u16(), Some(42));
+ /// assert_eq!(Value::U32(42).as_u16(), Some(42));
+ ///
+ /// assert_eq!(Value::U32(u32::MAX).as_u16(), None);
+ /// assert_eq!(Value::Bool(true).as_u16(), None);
+ /// ```
+ u16 => as_u16,
+
+ /// Return a `u32` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::U32(42).as_u32(), Some(42));
+ /// assert_eq!(Value::U64(42).as_u32(), Some(42));
+ ///
+ /// assert_eq!(Value::U64(u64::MAX).as_u32(), None);
+ /// assert_eq!(Value::Bool(true).as_u32(), None);
+ /// ```
+ u32 => as_u32,
+
+ /// Return a `u64` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::U64(42).as_u64(), Some(42));
+ /// assert_eq!(Value::U128(42).as_u64(), Some(42));
+ ///
+ /// assert_eq!(Value::U128(u128::MAX).as_u64(), None);
+ /// assert_eq!(Value::Bool(true).as_u64(), None);
+ /// ```
+ u64 => as_u64,
+
+ /// Return a `u128` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::U128(42).as_u128(), Some(42));
+ /// assert_eq!(Value::I32(42).as_u128(), Some(42));
+ ///
+ /// assert_eq!(Value::I32(-5).as_u128(), None);
+ /// assert_eq!(Value::Bool(true).as_u128(), None);
+ /// ```
+ u128 => as_u128,
+
+ /// Return a `usize` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::Usize(42).as_usize(), Some(42));
+ /// assert_eq!(Value::I8(42).as_usize(), Some(42));
+ ///
+ /// assert_eq!(Value::I8(-5).as_usize(), None);
+ /// assert_eq!(Value::Bool(true).as_usize(), None);
+ /// ```
+ usize => as_usize,
+}
diff --git a/vendor/valuable/src/visit.rs b/vendor/valuable/src/visit.rs
new file mode 100644
index 000000000..f91a04cad
--- /dev/null
+++ b/vendor/valuable/src/visit.rs
@@ -0,0 +1,459 @@
+use crate::*;
+
+/// Traverse a value's fields and variants.
+///
+/// Each method of the `Visit` trait is a hook that enables the implementor to
+/// observe value fields. By default, most methods are implemented as a no-op.
+/// The `visit_primitive_slice` default implementation will iterate the slice,
+/// calling `visit_value` with each item.
+///
+/// To recurse, the implementor must implement methods to visit the arguments.
+///
+/// # Examples
+///
+/// Recursively printing a Rust value.
+///
+/// ```
+/// use valuable::{NamedValues, Valuable, Value, Visit};
+///
+/// struct Print(String);
+///
+/// impl Print {
+/// fn indent(&self) -> Print {
+/// Print(format!("{} ", self.0))
+/// }
+/// }
+///
+/// impl Visit for Print {
+/// fn visit_value(&mut self, value: Value<'_>) {
+/// match value {
+/// Value::Structable(v) => {
+/// let def = v.definition();
+/// // Print the struct name
+/// println!("{}{}:", self.0, def.name());
+///
+/// // Visit fields
+/// let mut visit = self.indent();
+/// v.visit(&mut visit);
+/// }
+/// Value::Enumerable(v) => {
+/// let def = v.definition();
+/// let variant = v.variant();
+/// // Print the enum name
+/// println!("{}{}::{}:", self.0, def.name(), variant.name());
+///
+/// // Visit fields
+/// let mut visit = self.indent();
+/// v.visit(&mut visit);
+/// }
+/// Value::Listable(v) => {
+/// println!("{}", self.0);
+///
+/// // Visit fields
+/// let mut visit = self.indent();
+/// v.visit(&mut visit);
+/// }
+/// Value::Mappable(v) => {
+/// println!("{}", self.0);
+///
+/// // Visit fields
+/// let mut visit = self.indent();
+/// v.visit(&mut visit);
+/// }
+/// // Primitive or unknown type, just render Debug
+/// v => println!("{:?}", v),
+/// }
+/// }
+///
+/// fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
+/// for (field, value) in named_values {
+/// print!("{}- {}: ", self.0, field.name());
+/// value.visit(self);
+/// }
+/// }
+///
+/// fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+/// for value in values {
+/// print!("{}- ", self.0);
+/// value.visit(self);
+/// }
+/// }
+///
+/// fn visit_entry(&mut self, key: Value<'_>, value: Value<'_>) {
+/// print!("{}- {:?}: ", self.0, key);
+/// value.visit(self);
+/// }
+/// }
+///
+/// #[derive(Valuable)]
+/// struct Person {
+/// name: String,
+/// age: u32,
+/// addresses: Vec<Address>,
+/// }
+///
+/// #[derive(Valuable)]
+/// struct Address {
+/// street: String,
+/// city: String,
+/// zip: String,
+/// }
+///
+/// let person = Person {
+/// name: "Angela Ashton".to_string(),
+/// age: 31,
+/// addresses: vec![
+/// Address {
+/// street: "123 1st Ave".to_string(),
+/// city: "Townsville".to_string(),
+/// zip: "12345".to_string(),
+/// },
+/// Address {
+/// street: "555 Main St.".to_string(),
+/// city: "New Old Town".to_string(),
+/// zip: "55555".to_string(),
+/// },
+/// ],
+/// };
+///
+/// let mut print = Print("".to_string());
+/// valuable::visit(&person, &mut print);
+/// ```
+pub trait Visit {
+ /// Visit a single value.
+ ///
+ /// The `visit_value` method is called once when visiting single primitive
+ /// values. When visiting `Listable` types, the `visit_value` method is
+ /// called once per item in the listable type.
+ ///
+ /// Note, in the case of Listable types containing primitive types,
+ /// `visit_primitive_slice` can be implemented instead for less overhead.
+ ///
+ /// # Examples
+ ///
+ /// Visiting a single value.
+ ///
+ /// ```
+ /// use valuable::{Valuable, Visit, Value};
+ ///
+ /// struct Print;
+ ///
+ /// impl Visit for Print {
+ /// fn visit_value(&mut self, value: Value<'_>) {
+ /// println!("{:?}", value);
+ /// }
+ /// }
+ ///
+ /// let my_val = 123;
+ /// my_val.visit(&mut Print);
+ /// ```
+ ///
+ /// Visiting multiple values in a list.
+ ///
+ /// ```
+ /// use valuable::{Valuable, Value, Visit};
+ ///
+ /// struct PrintList { comma: bool };
+ ///
+ /// impl Visit for PrintList {
+ /// fn visit_value(&mut self, value: Value<'_>) {
+ /// match value {
+ /// Value::Listable(v) => v.visit(self),
+ /// value => {
+ /// if self.comma {
+ /// println!(", {:?}", value);
+ /// } else {
+ /// print!("{:?}", value);
+ /// self.comma = true;
+ /// }
+ /// }
+ /// }
+ /// }
+ /// }
+ ///
+ /// let my_list = vec![1, 2, 3, 4, 5];
+ /// valuable::visit(&my_list, &mut PrintList { comma: false });
+ /// ```
+ fn visit_value(&mut self, value: Value<'_>);
+
+ /// Visit a struct or enum's named fields.
+ ///
+ /// When the struct/enum is statically defined, all fields are known ahead
+ /// of time and `visit_named_fields` is called once with all field values.
+ /// When the struct/enum is dynamic, then the `visit_named_fields` method
+ /// may be called multiple times.
+ ///
+ /// See [`Structable`] and [`Enumerable`] for static vs. dynamic details.
+ ///
+ /// # Examples
+ ///
+ /// Visiting all fields in a struct.
+ ///
+ /// ```
+ /// use valuable::{NamedValues, Valuable, Value, Visit};
+ ///
+ /// #[derive(Valuable)]
+ /// struct MyStruct {
+ /// hello: String,
+ /// world: u32,
+ /// }
+ ///
+ /// struct Print;
+ ///
+ /// impl Visit for Print {
+ /// fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
+ /// for (field, value) in named_values {
+ /// println!("{:?}: {:?}", field, value);
+ /// }
+ /// }
+ ///
+ /// fn visit_value(&mut self, value: Value<'_>) {
+ /// match value {
+ /// Value::Structable(v) => v.visit(self),
+ /// _ => {} // do nothing for other types
+ /// }
+ /// }
+ /// }
+ ///
+ /// let my_struct = MyStruct {
+ /// hello: "Hello world".to_string(),
+ /// world: 42,
+ /// };
+ ///
+ /// valuable::visit(&my_struct, &mut Print);
+ /// ```
+ fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
+ let _ = named_values;
+ }
+
+ /// Visit a struct or enum's unnamed fields.
+ ///
+ /// When the struct/enum is statically defined, all fields are known ahead
+ /// of time and `visit_unnamed_fields` is called once with all field values.
+ /// When the struct/enum is dynamic, then the `visit_unnamed_fields` method
+ /// may be called multiple times.
+ ///
+ /// See [`Structable`] and [`Enumerable`] for static vs. dynamic details.
+ ///
+ /// # Examples
+ ///
+ /// Visiting all fields in a struct.
+ ///
+ /// ```
+ /// use valuable::{Valuable, Value, Visit};
+ ///
+ /// #[derive(Valuable)]
+ /// struct MyStruct(String, u32);
+ ///
+ /// struct Print;
+ ///
+ /// impl Visit for Print {
+ /// fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+ /// for value in values {
+ /// println!("{:?}", value);
+ /// }
+ /// }
+ ///
+ /// fn visit_value(&mut self, value: Value<'_>) {
+ /// match value {
+ /// Value::Structable(v) => v.visit(self),
+ /// _ => {} // do nothing for other types
+ /// }
+ /// }
+ /// }
+ ///
+ /// let my_struct = MyStruct("Hello world".to_string(), 42);
+ ///
+ /// valuable::visit(&my_struct, &mut Print);
+ /// ```
+ fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+ let _ = values;
+ }
+
+ /// Visit a primitive slice.
+ ///
+ /// This method exists as an optimization when visiting [`Listable`] types.
+ /// By default, `Listable` types are visited by passing each item to
+ /// `visit_value`. However, if the listable stores a **primitive** type
+ /// within contiguous memory, then `visit_primitive_slice` is called
+ /// instead.
+ ///
+ /// When implementing `visit_primitive_slice`, be aware that the method may
+ /// be called multiple times for a single `Listable` type.
+ ///
+ /// # Examples
+ ///
+ /// A vec calls `visit_primitive_slice` one time, but a `VecDeque` will call
+ /// `visit_primitive_slice` twice.
+ ///
+ /// ```
+ /// use valuable::{Valuable, Value, Visit, Slice};
+ /// use std::collections::VecDeque;
+ ///
+ /// struct Count(u32);
+ ///
+ /// impl Visit for Count {
+ /// fn visit_primitive_slice(&mut self, slice: Slice<'_>) {
+ /// self.0 += 1;
+ /// }
+ ///
+ /// fn visit_value(&mut self, value: Value<'_>) {
+ /// match value {
+ /// Value::Listable(v) => v.visit(self),
+ /// _ => {} // do nothing for other types
+ /// }
+ /// }
+ /// }
+ ///
+ /// let vec = vec![1, 2, 3, 4, 5];
+ ///
+ /// let mut count = Count(0);
+ /// valuable::visit(&vec, &mut count);
+ /// assert_eq!(1, count.0);
+ ///
+ /// let mut vec_deque = VecDeque::from(vec);
+ ///
+ /// let mut count = Count(0);
+ /// valuable::visit(&vec_deque, &mut count);
+ ///
+ /// assert_eq!(2, count.0);
+ /// ```
+ fn visit_primitive_slice(&mut self, slice: Slice<'_>) {
+ for value in slice {
+ self.visit_value(value);
+ }
+ }
+
+ /// Visit a `Mappable`'s entries.
+ ///
+ /// The `visit_entry` method is called once for each entry contained by a
+ /// `Mappable.`
+ ///
+ /// # Examples
+ ///
+ /// Visit a map's entries
+ ///
+ /// ```
+ /// use valuable::{Valuable, Value, Visit};
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert("hello", 123);
+ /// map.insert("world", 456);
+ ///
+ /// struct Print;
+ ///
+ /// impl Visit for Print {
+ /// fn visit_entry(&mut self, key: Value<'_>, value: Value<'_>) {
+ /// println!("{:?} => {:?}", key, value);
+ /// }
+ ///
+ /// fn visit_value(&mut self, value: Value<'_>) {
+ /// match value {
+ /// Value::Mappable(v) => v.visit(self),
+ /// _ => {} // do nothing for other types
+ /// }
+ /// }
+ /// }
+ ///
+ /// valuable::visit(&map, &mut Print);
+ /// ```
+ fn visit_entry(&mut self, key: Value<'_>, value: Value<'_>) {
+ let _ = (key, value);
+ }
+}
+
+macro_rules! deref {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<T: ?Sized + Visit> Visit for $ty {
+ fn visit_value(&mut self, value: Value<'_>) {
+ T::visit_value(&mut **self, value)
+ }
+
+ fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
+ T::visit_named_fields(&mut **self, named_values)
+ }
+
+ fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+ T::visit_unnamed_fields(&mut **self, values)
+ }
+
+ fn visit_primitive_slice(&mut self, slice: Slice<'_>) {
+ T::visit_primitive_slice(&mut **self, slice)
+ }
+
+ fn visit_entry(&mut self, key: Value<'_>, value: Value<'_>) {
+ T::visit_entry(&mut **self, key, value)
+ }
+ }
+ )*
+ };
+}
+
+deref! {
+ &mut T,
+ #[cfg(feature = "alloc")]
+ alloc::boxed::Box<T>,
+}
+
+/// Inspects a value by calling the relevant [`Visit`] methods with `value`'s
+/// data.
+///
+/// This method calls [`Visit::visit_value()`] with the provided [`Valuable`]
+/// instance. See [`Visit`] documentation for more details.
+///
+/// # Examples
+///
+/// Extract a single field from a struct. Note: if the same field is repeatedly
+/// extracted from a struct, it is preferable to obtain the associated
+/// [`NamedField`] once and use it repeatedly.
+///
+/// ```
+/// use valuable::{NamedValues, Valuable, Value, Visit};
+///
+/// #[derive(Valuable)]
+/// struct MyStruct {
+/// foo: usize,
+/// bar: usize,
+/// }
+///
+/// struct GetFoo(usize);
+///
+/// impl Visit for GetFoo {
+/// fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
+/// if let Some(foo) = named_values.get_by_name("foo") {
+/// if let Some(val) = foo.as_usize() {
+/// self.0 = val;
+/// }
+/// }
+/// }
+///
+/// fn visit_value(&mut self, value: Value<'_>) {
+/// if let Value::Structable(v) = value {
+/// v.visit(self);
+/// }
+/// }
+/// }
+///
+/// let my_struct = MyStruct {
+/// foo: 123,
+/// bar: 456,
+/// };
+///
+/// let mut get_foo = GetFoo(0);
+/// valuable::visit(&my_struct, &mut get_foo);
+///
+/// assert_eq!(123, get_foo.0);
+/// ```
+///
+/// [`Visit`]: Visit [`NamedField`]: crate::NamedField
+pub fn visit(value: &impl Valuable, visit: &mut dyn Visit) {
+ visit.visit_value(value.as_value());
+}