Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

682
vendor/valuable/src/enumerable.rs vendored Normal file
View File

@@ -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()]),
}
}
}

166
vendor/valuable/src/field.rs vendored Normal file
View File

@@ -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
}
}

157
vendor/valuable/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,157 @@
#![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);
//! ```
//!
//! # Related Crates
//!
//! - [`valuable-serde`] provides a bridge between `valuable` and the [`serde`]
//! serialization ecosystem. Using [`valuable_serde::Serializable`] allows any
//! type that implements [`Valuable`] to be serialized by any
//! [`serde::ser::Serializer`].
//!
//! [`valuable-serde`]: https://crates.io/crates/valuable-serde
//! [`serde`]: https://crates.io/crates/serde
//! [`valuable_serde::Serializable`]: https://docs.rs/valuable-serde/latest/valuable_serde/struct.Serializable.html
//! [`serde::ser::Serializer`]: https://docs.rs/serde/latest/serde/ser/trait.Serializer.html
#![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;

257
vendor/valuable/src/listable.rs vendored Normal file
View File

@@ -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()
}
}

191
vendor/valuable/src/mappable.rs vendored Normal file
View File

@@ -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, S> Valuable for std::collections::HashMap<K, V, S> {
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, S> Mappable for std::collections::HashMap<K, V, S> {
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()
}
}

222
vendor/valuable/src/named_values.rs vendored Normal file
View File

@@ -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<'_, '_> {}

428
vendor/valuable/src/slice.rs vendored Normal file
View File

@@ -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(()),
}

496
vendor/valuable/src/structable.rs vendored Normal file
View File

@@ -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>,
}

339
vendor/valuable/src/tuplable.rs vendored Normal file
View File

@@ -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 { .. })
}
}

339
vendor/valuable/src/valuable.rs vendored Normal file
View File

@@ -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)
}
}

876
vendor/valuable/src/value.rs vendored Normal file
View File

@@ -0,0 +1,876 @@
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::*;
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,
}

459
vendor/valuable/src/visit.rs vendored Normal file
View File

@@ -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());
}