try_ref/
lib.rs

1/// ### Example
2/// 
3/// ```no_run
4/// let a = TestStruct(TestEnum::AType(String::from("a_type")));
5/// let a: Result<&str, TestError> = a.try_as_ref();
6/// assert!(a.is_ok());
7/// 
8/// let a: TestStruct = TestStruct(TestEnum::BType(BType()));
9/// let a: Result<&str, TestError> = a.try_as_ref();
10/// assert!(a.is_err());
11/// 
12/// let b = TestStruct(TestEnum::BType(BType()));
13/// let b: Result<&BType, TestError> = b.try_as_ref();
14/// assert!(b.is_ok());
15/// 
16/// let b = TestStruct(TestEnum::AType(String::from("a_type")));
17/// let b: Result<&BType, TestError> = b.try_as_ref();
18/// assert!(b.is_err());
19/// ```
20pub trait TryAsRef<T: ?Sized> {
21    type Error: std::error::Error;
22    fn try_as_ref(&self) -> Result<&T, Self::Error>;
23}
24
25/// ### Example
26/// 
27/// ```no_run
28/// let mut a = TestStruct(TestEnum::AType(String::from("a_type")));
29/// let a: Result<&mut str, TestError> = a.try_as_mut();
30/// assert!(a.is_ok());
31/// 
32/// let mut a: TestStruct = TestStruct(TestEnum::BType(BType()));
33/// let a: Result<&mut str, TestError> = a.try_as_mut();
34/// assert!(a.is_err());
35/// 
36/// let mut b = TestStruct(TestEnum::BType(BType()));
37/// let b: Result<&mut BType, TestError> = b.try_as_mut();
38/// assert!(b.is_ok());
39/// 
40/// let mut b = TestStruct(TestEnum::AType(String::from("a_type")));
41/// let b: Result<&mut BType, TestError> = b.try_as_mut();
42/// assert!(b.is_err());
43/// ```
44pub trait TryAsMut<T: ?Sized> {
45    type Error: std::error::Error;
46    fn try_as_mut(&mut self) -> Result<&mut T, Self::Error>;
47}
48
49#[cfg(test)]
50mod tests {
51    use crate::{TryAsRef, TryAsMut};
52
53    struct TestStruct(TestEnum);
54
55    #[derive(Debug, thiserror::Error)]
56    enum TestError {
57        #[error(transparent)] 
58        InvalidType(anyhow::Error) 
59    }
60
61    impl TryAsRef<str> for TestStruct {
62        type Error = TestError;
63        fn try_as_ref(&self) -> Result<&str, Self::Error> {
64            match &self.0 {
65                TestEnum::AType(s) => Ok(s),
66                TestEnum::BType(_) => Err(TestError::InvalidType(anyhow::Error::msg("cannot get reference to str"))),
67            }
68        }
69    }
70
71    impl TryAsRef<BType> for TestStruct {
72        type Error = TestError;
73        fn try_as_ref(&self) -> Result<&BType, Self::Error> {
74            match &self.0 {
75                TestEnum::AType(_) => Err(TestError::InvalidType(anyhow::Error::msg("cannot get reference to BType"))),
76                TestEnum::BType(b) => Ok(b),
77            }
78        }
79    }
80
81    impl TryAsMut<str> for TestStruct {
82        type Error = TestError;
83        fn try_as_mut(&mut self) -> Result<&mut str, Self::Error> {
84            let s = match &mut self.0 {
85                TestEnum::AType(ref mut s) => s,
86                TestEnum::BType(_) => return Err(TestError::InvalidType(anyhow::Error::msg("cannot get mutable reference to str"))),
87            };
88            Ok(s)
89        }
90    }
91
92    impl TryAsMut<BType> for TestStruct {
93        type Error = TestError;
94        fn try_as_mut(&mut self) -> Result<&mut BType, Self::Error> {
95            let s = match &mut self.0 {
96                TestEnum::AType(_) => return Err(TestError::InvalidType(anyhow::Error::msg("cannot get mutable reference to BType"))),
97                TestEnum::BType(ref mut b) => b,
98            };
99            Ok(s)
100        }
101    }
102
103    enum TestEnum { AType(String), BType(BType) }
104    struct BType();
105
106    #[test]
107    fn test_try_as_ref() -> anyhow::Result<()> {
108        let a = TestStruct(TestEnum::AType(String::from("a_type")));
109        let a: Result<&str, TestError> = a.try_as_ref();
110        assert!(a.is_ok());
111
112        let a: TestStruct = TestStruct(TestEnum::BType(BType()));
113        let a: Result<&str, TestError> = a.try_as_ref();
114        assert!(a.is_err());
115
116        let b = TestStruct(TestEnum::BType(BType()));
117        let b: Result<&BType, TestError> = b.try_as_ref();
118        assert!(b.is_ok());
119
120        let b = TestStruct(TestEnum::AType(String::from("a_type")));
121        let b: Result<&BType, TestError> = b.try_as_ref();
122        assert!(b.is_err());
123        Ok(())
124    }
125
126    #[test]
127    fn test_try_as_mut() -> anyhow::Result<()> {
128        let mut a = TestStruct(TestEnum::AType(String::from("a_type")));
129        let a: Result<&mut str, TestError> = a.try_as_mut();
130        assert!(a.is_ok());
131
132        let mut a: TestStruct = TestStruct(TestEnum::BType(BType()));
133        let a: Result<&mut str, TestError> = a.try_as_mut();
134        assert!(a.is_err());
135
136        let mut b = TestStruct(TestEnum::BType(BType()));
137        let b: Result<&mut BType, TestError> = b.try_as_mut();
138        assert!(b.is_ok());
139
140        let mut b = TestStruct(TestEnum::AType(String::from("a_type")));
141        let b: Result<&mut BType, TestError> = b.try_as_mut();
142        assert!(b.is_err());
143        Ok(())
144    }
145}