5 releases
0.1.4 | Oct 12, 2020 |
---|---|
0.1.3 | Oct 12, 2020 |
0.1.2 | Oct 12, 2020 |
0.1.1 | Oct 10, 2020 |
0.1.0 | Oct 10, 2020 |
#1631 in Rust patterns
12KB
129 lines
trait-union
This crate provides a macro that generates a trait-union type. That is, a trait object type which can contain any one of a pre-determined set of implementors.
The generated type does not allocate. The size of the type is the size of the largest variant plus some constant overhead.
NOTE: As of rustc 1.47, you must enable the untagged_unions
feature to store
non-Copy types in a trait-union. This will change
soon.
Example
use trait_union::trait_union;
use std::fmt::Display;
trait_union! {
/// Container can contain either an i32, a &'static str, or a bool.
union Container: Display = i32 | &'static str | bool;
}
let mut container = Container::new(32);
assert_eq!(container.to_string(), "32");
container = Container::new("Hello World");
assert_eq!(container.to_string(), "Hello World");
container = Container::new(true);
assert_eq!(container.to_string(), "true");
Implementation
The generated type looks roughly as follows:
struct Container {
data: union {
variant1: i32,
variant2: &'static str,
variant3: bool,
},
vtable: *mut (),
}
Its size is therefore similar to the size of an enum
with one variant per implementor.
Depending on the number of implementors, compile times should be significantly lower than
with an enum
. The run-time performance is similar to that of Box<dyn Trait>
.
License
This project is licensed under either of
- Apache License, Version 2.0
- MIT License
at your option.
Dependencies
~1.5MB
~38K SLoC