Enum valuable::EnumDef

source ·
#[non_exhaustive]
pub enum EnumDef<'a> {
    Static {
        name: &'static str,
        variants: &'static [VariantDef<'static>],
    },
    Dynamic {
        name: &'a str,
        variants: &'a [VariantDef<'a>],
    },
}
Expand description

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.

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Static

Fields

This variant is marked as non-exhaustive
Non-exhaustive enum variants could have additional fields added in future. Therefore, non-exhaustive enum variants cannot be constructed in external crates and cannot be matched against.
§name: &'static str

The enum’s name

§variants: &'static [VariantDef<'static>]

The enum’s variants

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());
§

Dynamic

Fields

This variant is marked as non-exhaustive
Non-exhaustive enum variants could have additional fields added in future. Therefore, non-exhaustive enum variants cannot be constructed in external crates and cannot be matched against.
§name: &'a str

The enum’s name

§variants: &'a [VariantDef<'a>]

The enum’s variants

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

Implementations§

source§

impl<'a> EnumDef<'a>

source

pub const fn new_static( name: &'static str, variants: &'static [VariantDef<'static>] ) -> 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);
source

pub const fn new_dynamic( name: &'a str, variants: &'a [VariantDef<'a>] ) -> EnumDef<'a>

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))]
);
source

pub fn name(&self) -> &str

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());
source

pub fn variants(&self) -> &[VariantDef<'_>]

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());
source

pub fn is_static(&self) -> bool

Returns true if the enum is statically defined.

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());
source

pub fn is_dynamic(&self) -> bool

Returns true if the enum is dynamically defined.

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

Trait Implementations§

source§

impl<'a> Debug for EnumDef<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for EnumDef<'a>

§

impl<'a> Send for EnumDef<'a>

§

impl<'a> Sync for EnumDef<'a>

§

impl<'a> Unpin for EnumDef<'a>

§

impl<'a> UnwindSafe for EnumDef<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

const: unstable · source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
const: unstable · source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.