Expand description
Macros and traits to ease using enums whose sole purpose is to enumerate a set of types.
It exports a set of traits that help to this end:
traits::TryAsRef- likeAsRef<T>, but allowed to failtraits::TryAsMut- likeAsMut<T>, but allowed to failtraits::TypedContainer- inspect types of a container
And a set of macros that derive implementations from these and some standard traits, namely:
macros::Fromto convert from the types to the enummacros::TryIntoto convert from the enum back into the typesmacros::TryAsMutto get references of the values of the enummacros::TryAsRefto get mutable references of the values of the enummacros::TypedContainerto inspect the type in the enum
To derive the traits for an enum, the enum has to have the following shape:
- Each variant must have exactly one unnamed parameter
- Each variant argument type must appear at most once
See also:
- crate
macros(re-export oftry_as_macros) - crate
traits(re-export oftry_as_traits)
Example
Assume we have an enum that enumerates values of i64, String and bool:
enum Value{
Number(i64),
String(String),
Bool(bool)
}And we want to convert between this enum and values of types i64, String and bool.
This crate exposes the following macros to ease this conversion:
use try_as::macros;
#[derive(macros::From, macros::TryInto, Debug)]
enum Value{
Number(i64),
String(String),
Bool(bool)
}
// Convert to `Value` from `i64`, `String` or `bool` using `into`/`from`:
let x = Value::from(0);
let name = Value::from("Hello".to_owned());
let yes_or_no: Value = false.into();
// Convert back with `try_into`
let maybe_i64: Result<i64, _> = x.try_into();
assert_eq!(maybe_i64.unwrap(), 0);
let maybe_i64: Result<i64, Value> = name.try_into();
assert!(maybe_i64.is_err());
If we only need a reference to the value, we can use the macros TryAsRef and TryAsMut,
which derive implementations for the new traits traits::TryAsRef and traits::TryAsMut, respectively:
use try_as::{
traits::{TryAsRef, TryAsMut},
macros,
};
#[derive(macros::TryAsRef, macros::TryAsMut)]
enum Value{
Number(i64),
String(String),
Bool(bool)
}
let mut x = Value::Number(0);
let x_ref: &i64 = x.try_as_ref().unwrap();
assert_eq!(*x_ref, 0);
let x_mut: &mut i64 = x.try_as_mut().unwrap();
*x_mut = 4;
let x_ref: &i64 = x.try_as_ref().unwrap();
assert_eq!(*x_ref, 4);
let str_ref: Option<&String> = x.try_as_ref();
assert!(str_ref.is_none());Finally, to inspect the type, we can use the trait traits::TypedContainer, which allows
us to look at the std::any::TypeId of the contained type:
use try_as::{
traits::TypedContainer,
macros
};
#[derive(macros::TypedContainer)]
enum Value{
Number(i64),
String(String),
Bool(bool)
}
let x = Value::Number(0);
let boolean: Value = Value::Bool(false);
assert!(x.holds::<i64>());
assert!(!boolean.holds::<i64>());
assert!(std::any::TypeId::of::<bool>() == boolean.type_id());
Re-exports
pub extern crate try_as_macros as macros;pub extern crate try_as_traits as traits;