odin-union 0.1.0

Dependency-free shorthand for Rust enums whose variants wrap same-named types
Documentation
  • Coverage
  • 0%
    0 out of 2 items documented0 out of 1 items with examples
  • Size
  • Source code size: 48.04 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 258.53 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 2s Average build duration of successful builds.
  • all releases: 2s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Sisyphus1813/odin-union
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • Sisyphus1813

odin-union

odin-union provides a dependency-free attribute macro for declaring Rust enums whose variants contain same-named types.

Instead of repeating each type:

enum Thing {
    Person(Person),
    Animal(Animal),
}

write:

use odin_union::odin_union;

struct Person {
    name: String,
}

struct Animal {
    species: String,
}

#[odin_union]
enum Thing {
    Person,
    Animal,
}

The macro expands the declaration to the ordinary payload enum above. It also generates From<Person> for Thing and From<Animal> for Thing, so values can be wrapped with .into():

# use odin_union::odin_union;
# struct Person { name: String }
# struct Animal { species: String }
# #[odin_union]
# enum Thing { Person, Animal }
let person = Person {
    name: "Ada".to_owned(),
};

let thing: Thing = person.into();

match thing {
    Thing::Person(person) => assert_eq!(person.name, "Ada"),
    Thing::Animal(_) => unreachable!(),
}

This is declaration shorthand, not a new runtime representation. The result is a normal Rust enum: its tag and active payload are stored together, matching, derives, visibility, and attributes continue to work normally, and no runtime support library is involved.

Rules

  • Every listed variant must be a bare unit variant such as Person.
  • A same-named type must be in scope at the enum declaration.
  • The source enum cannot be generic. The macro cannot infer which generic arguments should be supplied to each same-named payload type.
  • A variant-level #[cfg(...)] attribute is copied to the generated From implementation.
  • Manually implementing the same From<T> conversion will conflict with the generated implementation.
  • Rust does not perform implicit user-defined conversions. Use .into(), Thing::from(value), or Thing::Person(value).

The crate has no dependencies and supports Rust 1.85 or newer.