typetrait
Helper macro for generating boilerplate for more type safe APIs.
For example, consider an API that receives user input:
We might want to make sure that we have validated that data.email contains a valid email address before we use it.
This is possible by making Data generic over "whether or not it has been validated":
// generates a trait called Status, and types Validated and Unvalidated that implement Status
union!
With this setup, we can now prevent unvalidated data from being used at compile time:
// data received from user input is considered unvalidated
// only validated data should be used by the rest of the application
// convert unvalidated data to validated data (by validating it!)
This API is now significantly harder to misuse. Instead of requiring the programmer to keep track of which data is validated and which isn't, this work is offloaded to the compiler.
This pattern is widely applicable, for example:
- Various data might be
ValidatedorUnvalidated- this could be especially useful in security contexts, for example a
SessionToken<Validated>could be required to make a particular database request
- this could be especially useful in security contexts, for example a
- GPIO pins could be
EnabledorDisabled, as well asInputorOutput(see https://docs.rust-embedded.org/book/design-patterns/hal/gpio.html for a more thorough example) - When making a safe Rust interface to some FFI code, you may have to encode the state of that data (for example
Initialized/Uninitialized/Disposed)
Details
Each trait generated by union! is "sealed", meaning it cannot be implemented outside of the module they are defined in. They generate a private module with a supertrait which is implemented for only the types given in the macro.
Each type is an empty enum (i.e. an enum with no variants) and so cannot be instantiated. Note that these types are almost exclusively used with PhantomData, since they only ever exist as concrete values for type parameters, but never as values themselves (there are no possible values of an empty enum).