1pub trait TryAsRef<T: ?Sized> {
21 type Error: std::error::Error;
22 fn try_as_ref(&self) -> Result<&T, Self::Error>;
23}
24
25pub 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}