only-cliches / NoProto

Flexible, Fast & Compact Serialization with RPC
MIT License
373 stars 14 forks source link

How to model a tagged union? #12

Open thedodd opened 3 years ago

thedodd commented 3 years ago

Awesome work here! Reviewing the documentation, I don't see an immediately obvious option for being able to specify that a field may be one of a set of types. In Rust this would typically look like:

enum Variants {
    ObjA(ObjA),
    ObjB(ObjB),
}

I see that enums can be used for a known collection of ordered strings, and I see that there is also the any type. Would the idea be to use a combination of those items within a struct?

only-cliches commented 3 years ago

Hey thanks for opening an issue!

There is no tagged union type in the library yet and I wouldn't recommend using the any type. The any type is really an escape hatch if you absolutely need untyped data.

I'm actually working on a union type right now, should have it deployed within a week or so.

I'm just trying to figure how to make the api as simple and usable as possible.

I think the schemas are going to look like this:

union({default: "variant_1", types: {
    variant_1: string({default: "Hello"}),
    variant_2: struct({fields ... }),
    variant_3: u8()
}});

Getting the default property to work in a common sense way is proving to be a challenge, Union types might not have a default property when I finalize the feature. (But I'm really hoping I can make it work!)

And the API is going to be something like this:

// assuming the schema above
let buffer = factory.new_buffer(None);

buffer.set(&["variant_1"], "testing");

assert_eq!(buffer.get(&["variant_1"], Some("testing"));
assert_eq!(buffer.get(&["variant_2"], None);
assert_eq!(buffer.get(&["variant_3"], None);

// discover what value the union currently has
let unionVal: NP_Union = buffer.get(&[]);
assert_eq!(unionVal, NP_Union::Value("variant_1"));

There are other complicated matters as well, like nesting unions that need to be figured out.

I'll post on this issue once the feature is live!