tokio-rs / valuable

MIT License
185 stars 19 forks source link

`dyn Display` primitive value #86

Open hawkw opened 2 years ago

hawkw commented 2 years ago

In some cases, it may be desirable for types implementing Valuable to record themselves as a pre-formatted human-readable text representation. Currently, this is only possible with the Value::String variant, which takes a &'a str.

For types that want to record themselves using a Display (or Debug) implementation, though, Value::String isn't really sufficient. Because it takes a borrowed string slice, those types would have to allocate ahead of time and store their own formatted representation, so that the borrowed string slice can be handed out in their Valuable impls. This is not ideal.

Therefore, we should probably add &dyn fmt::Display as a primitive Value variant.

fluffysquirrels commented 11 months ago

I would also like this or a similar solution.

The workaround I use is to return a single-value tuple that is a String. This works well enough, but does add a layer of noise in the output I would prefer to avoid.

Here's an example:

struct MyStruct;

impl Valuable for MyStruct {
    fn as_value(&self) -> Value<'_> {
        // We don't store a String of the value, so can't return an &str
        // and use `Value<'a>::String(&'a str)`, encode as a tuple instead.
        Value::Tuplable(self)
    }

    fn visit(&self, visit: &mut dyn valuable::Visit) {
        let s: String = foo();
        let val = Value::String(s.as_str());
        visit.visit_unnamed_fields(&[val]);
    }
}

impl Tuplable for MyStruct {
    fn definition(&self) -> TupleDef {
        TupleDef::new_static(1)
    }
}