Trait valuable::Structable

source ·
pub trait Structable: Valuable {
    // Required method
    fn definition(&self) -> StructDef<'_>;
}
Expand description

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

Required Methods§

source

fn definition(&self) -> StructDef<'_>

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

Trait Implementations§

source§

impl Debug for dyn Structable + '_

source§

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

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a (dyn Structable + 'a)> for Value<'a>

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

fn from(src: &'a dyn Structable) -> Value<'a>

Converts to this type from the input type.

Implementations on Foreign Types§

source§

impl<T: ?Sized + Structable> Structable for &T

source§

fn definition(&self) -> StructDef<'_>

source§

impl<T: ?Sized + Structable> Structable for Arc<T>

source§

fn definition(&self) -> StructDef<'_>

source§

impl<T: ?Sized + Structable> Structable for &mut T

source§

fn definition(&self) -> StructDef<'_>

source§

impl<T: ?Sized + Structable> Structable for Rc<T>

source§

fn definition(&self) -> StructDef<'_>

source§

impl<T: ?Sized + Structable> Structable for Box<T>

source§

fn definition(&self) -> StructDef<'_>

Implementors§