Skip to main content

atb_types/
lib.rs

1#[cfg(feature = "jwt")]
2pub mod jwt;
3
4pub mod prelude {
5    pub use chrono;
6    pub use uuid;
7
8    pub use super::*;
9
10    #[cfg(feature = "jwt")]
11    pub use jwt::*;
12}
13
14pub use chrono::{Duration, Utc};
15pub use uuid::Uuid;
16
17pub type DateTime = chrono::DateTime<Utc>;
18
19#[derive(Debug)]
20pub struct Take<T>(Option<T>);
21
22impl<T> Take<T> {
23    pub fn new(item: T) -> Self {
24        Self(Some(item))
25    }
26
27    pub fn take(&mut self) -> Option<T> {
28        std::mem::take(&mut self.0)
29    }
30
31    pub fn insert(&mut self, item: T) -> &mut T {
32        self.0.insert(item)
33    }
34}
35
36impl<T> std::ops::Deref for Take<T> {
37    type Target = T;
38
39    fn deref(&self) -> &Self::Target {
40        match &self.0 {
41            Some(t) => t,
42            None => panic!("value is already taken"),
43        }
44    }
45}
46
47impl<T> std::ops::DerefMut for Take<T> {
48    fn deref_mut(&mut self) -> &mut Self::Target {
49        match self.0 {
50            Some(ref mut t) => t,
51            None => panic!("value is already taken"),
52        }
53    }
54}
55
56#[cfg(test)]
57mod test {
58    use super::*;
59    use std::ops::Deref;
60
61    #[derive(Debug)]
62    struct Container {
63        data: Take<String>,
64    }
65
66    impl Container {
67        fn take_and_overwrite(&mut self) {
68            let _ = self.data.take();
69            self.overwrite();
70        }
71
72        fn overwrite(&mut self) {
73            //this will panic, and is exactly what we are trying to prevent
74            *self.data = "something".to_owned();
75        }
76    }
77
78    #[test]
79    fn it_can_be_mutated() {
80        let mut field = Container {
81            data: Take::new("hello".to_owned()),
82        };
83
84        let f = &mut field;
85        let inner = &f.data;
86        *f.data = [inner, " ", "world"].concat();
87
88        assert_eq!(f.data.deref(), &"hello world".to_owned());
89    }
90
91    #[test]
92    #[should_panic]
93    fn it_should_panic_on_double_take() {
94        let mut field = Container {
95            data: Take::new("hello".to_owned()),
96        };
97
98        field.take_and_overwrite();
99    }
100}