Currently, there is no way to extend an enum from the outside, and for regular enumerables this should remain the case. This topic will consider an approach to use traits as enum extenders. The solution is to make use of trait hierarchies and consider them as enum roots. The idea is to add the syntax enum trait
// Will be the "parent" enumerable
pub enum trait Enum { ... }
// Will be an "enum member"
pub struct Member1;
impl Enum for Member1 { ... }
// Control flow
let value: Enum
match value { // because Enum is of an 'enum trait', this match arm is recognized as one by the analyzer.
Member1 => ...,
Member2 { ... } => ...,
Member3 ( ... ) => ...,
Member4 _ => ..., // without brackets, this simply acts as a cast and makes `value` usable in match arm.
_ => ... // This should be required as the trait is defined as an enum trait (=extensible, non-exhaustive)
}
Under the hood, the TypeId struct and type_id() intrinsic as referenced by the Rust Stdlib would act as the discriminator and essentially replace the match arms with type id comparators.
match value.type_id() {
TypeId::of::< Member1 >() => ... // Assume to be Member1 in this scope.
...
}
The usage is to define extensible by other modules enums, but not require too much storage space like comparing string identifiers or other. Examples include having an "error" type for a parser that could be extended with custom tokens and custom errors. Note, that the compiler should always require the wildcard match, as these enums are non-exhaustive.
Since traits and structs are always imported by path, name collisions can be ignored, since this part is considered by import logic.
Per default, this should be the default implementation, which any enum trait member should implement (built-in)
pub enum trait Enum {
pub fn discriminator(&self) -> u128 {
self.type_id()
}
}
The trait 'Any' should become an enum trait. This allows for direct matching and is backwards compatible, since enum traits can still act as regular traits.
let any: Any;
match any {
String _ => println!("Received a string: {value}"),
usize _ => println!("Received a number: {}", "+".repeat(value)),
_ => println!("I don't know this type."),
}