Enums and reusable type constraints


I’m building an implementation in Rust of an underlying serializable data model. The underlying model has atomic primitives and union types (among others).

I.e., imagine a set of name/value pairs, where, like JSON, the value can be an atom, an object, or a list of atoms or object or a union of atoms or objects.

Just atomic primitives would be pretty easy: build a enum of the underlying primitives (similar to what rustc_serializable or serde does with JSON primitives).

Dealing with arbitrary union types is a bit more tricky because I can’t easily constrain the union to subsets of the primitives (refinement types?).

I can model the primitives, create an Atom or Value enum, and then create an enum for each union type, but that’s a lot of indirection.

Is there a cleaner way of using Rust’s type system that’s obvious? I’ve thought, e.g., about a marker trait and using a generic type constrained only to marked items, but everything ends up looking super complex…


Using variants to represent expressions is fine. This sort of thing is well done using such variants to represent a statement, expression, values and so on.

Here (I don’t know if this will help) an example of a simple system of expressions:

enum Expr {
    Add(Box<Expr>, Box<Expr>),
    Sub(Box<Expr>, Box<Expr>),

impl Expr {
    fn eval(&self) -> i32 {
        match *self {
            Expr::Add(ref a, ref b) =>
                eval(a) + eval(b),
            Expr::Sub(ref a, ref b) =>
                eval(a) - eval(b),
            Expr::Num(x) =>

edit: But, in most of cases, there’s lots of crates that does this job as well. Like parsers, lexers and so on. I’d recommend you to look for one.