Extending enums is not possible, but within my own crate, I'd like to be able to support behavior that I've only been able to think how to do by
- extending enums, (not possible, but maybe alternative since these are all types in my crate)
- much unwrapping in
match
statements - or repeatedly implementing functions down the "tree" of enums.
I'm working to implement a parser for specification of a set by an operator (typically comparison, but I've got others) and a typed element. i.e.
let s: ">0".to_string();
let positives = Set<OrdOperator<u64>, u64>::from_str(&s).unwrap();
// design not constrained to need ^this type, but as possible illustration.
assert_eq!(positives, Set::new(OrdOperator::Range(RangeOperator::Greater), 0u64));
assert!(positives.contains(1u64));
But also to support other operators on other types, i.e.
let s: "[[hello".to_string();
let greetings = Set<ExtendedOrdOperator<Sentences>, Sentences>::from_str(&s).unwrap();
assert_eq!(greetings, Set::new(ExtendedOrdOperator::String(StringOperator::StartsWith), "hello"));
assert!(greetings.contains("hello world"));
Below is the mess that defines all the operator kinds I use as enums and then enums for the operators that aren't nested.
// operators that are unions of simple operators
pub enum ExtendedOrdOperator {
Ordering(OrdOperator),
String(StringOperator),
}
pub enum OrdOperator {
/// Specifies a range
Range(RangeOperator),
/// Specifies an exact
Exact(EqualityOperator),
}
// simple operator
pub enum RangeOperator {
Greater,
GreaterEquals,
Less,
LessEquals,
}
pub enum StringOperator {
StartsWith,
NotStartsWith,
Contains,
NotContains,
}
pub enum EqualityOperator {
Equals,
NotEquals,
}
From this, I feel like my options to implement similar behavior are to have
- trees of matches statements each time
- implement a method for each of these enums of a similar signature, both for parsing and membership and whatever else I may need them all to do. This would be at the unions of operators level as well as the simple operator level
- unit enums for all the operators that are leaves, and somehow be smart about std::ops::Not for the parsed representation of unexplicitly specified operators.
I looked at this post, since maybe that macro is a good place to start for one that'll generate the enums. After writing all this option 3 above seems the most promising, but I'd like some input from others here on how I'm thinking about this, I've not a background of programming with interfaces and I think my excitement to use them sometimes ends up in things being more complex than needed.