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