#serialization #no-std

no-std valuable

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

2 unstable releases

0.1.0 Jan 3, 2022
0.0.0 Mar 9, 2021

#409 in Debugging

Download history 502153/week @ 2024-01-23 524156/week @ 2024-01-30 513367/week @ 2024-02-06 511194/week @ 2024-02-13 557481/week @ 2024-02-20 557313/week @ 2024-02-27 547536/week @ 2024-03-05 549164/week @ 2024-03-12 573970/week @ 2024-03-19 549837/week @ 2024-03-26 606800/week @ 2024-04-02 590056/week @ 2024-04-09 610776/week @ 2024-04-16 593803/week @ 2024-04-23 542758/week @ 2024-04-30 457796/week @ 2024-05-07

2,311,647 downloads per month
Used in 7,957 crates (24 directly)

MIT license

130KB
1.5K SLoC

Valuable

Valuable provides object-safe value inspection. Use cases include passing structured data to trait objects and object-safe serialization.

License

This project is licensed under the MIT license.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Valuable by you, shall be licensed as MIT, without any additional terms or conditions.


lib.rs:

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.

let hello_world = HelloWorld { message: Message::HelloWorld };
hello_world.visit(&mut Print);

Dependencies

~210KB