One issue I've had with robust/extensible ffi code is that many APIs return an almost-but-not-quite fixed set of integer codes treated as "enums". That is, there is a potential for having to handle previously unused/reserved values as a plain numeric error code or whatever, often just for logging or pass-through purposes. This can be represented in Rust as-is, but not efficiently, as additional space is required to discriminate between the fixed set and the unrecognised set. Converting back-and-forth is a pain too.
Similarly, many APIs use sets or ranges of integers. Parsing comes to mind, where lexers often return integer streams that are treated as enums. Matching on these can benefit from compiler-generated code that's difficult to roll by hand.
What I have seen is that library developers simply use constants everywhere, which is the messy filth I associated with Java and C++, not newer languages with fist-class enums such as C# and Rust.
Has anyone proposed this type of feature in Rust:
// The size of this is always 4 bytes!
#[repr(u32)]
enum ApiStatus {
Success = 0,
ErrorFoo = 1,
ErrorBar = 2,
Warnings = 3..100, // Ranges of values
Info = ( 200, 210, 211 ), // Discontinuous sets
Unknown = _ // optionally "everything else"
}
When constructing such an enum, any variant with multiple possible values would have to have the underlying value passed in during construction, or cast from the underlying integer type using the as
keyword. E.g.:
let status = 210 as ApiStatus; // one of the three "Info" messages
Thoughts?