I am making Rust bindings for an existing proprietary C library. The library defines a fairly large enum containing possible status and error codes, i.e.:
enum RET_CODE
{
STA_OK = 0,
STA_SOME_CONDITION,
STA_ANOTHER_CONDITION,
/* ... more status codes ... */
ERR_INTERNAL,
ERR_SYSTEM,
ERR_INPUT_OUTPUT,
/* ... more than 100 other error codes ... */
};
Library functions return these RET_CODE
values. Status codes start with STA_
and do not mean a failure; they signal various conditions. Error codes start with ERR_
.
My idea is to split this enum into two Rust enums, StatusCode
and ErrorCode
, like that:
enum StatusCode {
Ok = ffi::RET_CODE::STA_OK,
SomeCondition = ffi::RET_CODE::SOME_CONDITION,
AnotherCondition = ffi::RET_CODE::ANOTHER_CONDITION,
// ...
}
enum ErrorCode {
Internal = ffi::RET_CODE::ERR_INTERNAL,
System = ffi::RET_CODE::ERR_SYSTEM,
InputOutput = ffi::RET_CODE::ERR_INPUT_OUTPUT,
// ...
}
Rust wrapper functions will then return std::result::Result<StatusCode, ErrorCode>
. However, I do not want to define those Rust enums manually, since the status and error codes in the C library are subject to change, and it is quite likely that I will forget to update the Rust bindings. Modifying the C library is not an option.
Is it possible to use Rust macros (or something else) to produce those Rust enums from the single C API enum? It would be great to rename the variants as well (i.e. STA_SOME_CONDITION
would become SomeCondition
), but this could apparently be handled by bindgen's ParseCallbacks
.