valuable 0.1.0

Object-safe value inspection, used to pass un-typed structured data across trait-object boundaries.
Documentation

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