enum_conversion_traits/
lib.rs

1use std::{error::Error, fmt};
2
3/// Custom errors for this crate. Keeps a record of
4/// the enum and requested type that produced the error
5#[derive(Debug)]
6pub struct EnumConversionError {
7    pub name: String,
8    pub requested_type: String,
9}
10
11impl EnumConversionError {
12    /// Makes the appropriate error message for when get_variant fails
13    pub fn new(name: &str, requested_type: &str) -> EnumConversionError {
14        EnumConversionError {
15            name: name.to_string(),
16            requested_type: requested_type.to_string(),
17        }
18    }
19}
20impl Error for EnumConversionError {}
21
22impl fmt::Display for EnumConversionError {
23    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24        write!(
25            f,
26            "EnumConversionError :: Active field of enum <{}> is not of type <{}>",
27            self.name, self.requested_type,
28        )
29    }
30}
31
32/// This is a helper trait for implementing the [`TryTo`] and
33/// [`std::convert::TryFrom`] traits on enums. Is uses marker structs
34/// to uniquely identify a type in the enum. This avoids
35/// relying on [`std::any::TypeId`] which is limited to types
36/// that are `'static`.
37pub trait GetVariant<T, Marker> {
38    fn get_variant(self) -> Result<T, EnumConversionError>;
39    fn get_variant_ref(&self) -> Result<&T, EnumConversionError>;
40    fn get_variant_mut(&mut self) -> Result<&mut T, EnumConversionError>;
41}
42
43/// Not all enums can have the [`std::convert::TryFrom`] trait derived
44/// on them because of rules around implementing foreign traits on
45/// foreign types.
46///
47/// This trait provides a similar interface that does not have this
48/// issue. It closely mimics the [`std::convert::TryInto`] trait.
49pub trait TryTo<T> {
50    type Error;
51    fn try_to(self) -> Result<T, Self::Error>;
52}