maycoon_core/
reference.rs1use std::ops::Deref;
2use std::sync::RwLockReadGuard;
3
4pub enum Ref<'a, T> {
10 Owned(T),
12 Borrow(&'a T),
14 Ref(std::cell::Ref<'a, T>),
16 ReadGuard(RwLockReadGuard<'a, T>),
18}
19
20impl<'a, T> Deref for Ref<'a, T> {
21 type Target = T;
22
23 #[inline(always)]
24 fn deref(&self) -> &Self::Target {
25 match self {
26 Ref::Owned(value) => value,
27 Ref::Borrow(value) => value,
28 Ref::Ref(value) => value,
29 Ref::ReadGuard(value) => value,
30 }
31 }
32}
33
34impl<'a, T> From<T> for Ref<'a, T> {
35 #[inline(always)]
36 fn from(value: T) -> Self {
37 Ref::Owned(value)
38 }
39}
40
41impl<'a, T> From<&'a T> for Ref<'a, T> {
42 #[inline(always)]
43 fn from(value: &'a T) -> Self {
44 Ref::Borrow(value)
45 }
46}
47
48impl<'a, T> From<std::cell::Ref<'a, T>> for Ref<'a, T> {
49 #[inline(always)]
50 fn from(value: std::cell::Ref<'a, T>) -> Self {
51 Ref::Ref(value)
52 }
53}
54
55impl<'a, T> From<RwLockReadGuard<'a, T>> for Ref<'a, T> {
56 #[inline(always)]
57 fn from(value: RwLockReadGuard<'a, T>) -> Self {
58 Ref::ReadGuard(value)
59 }
60}
61
62#[cfg(all(test, feature = "test"))]
63mod tests {
64 use crate::reference::Ref;
65 use std::cell::RefCell;
66 use std::fmt::Debug;
67 use std::sync::RwLock;
68
69 #[test_case::test_case(1; "with int")]
70 #[test_case::test_case("Test".to_string(); "with string")]
71 #[test_case::test_case(vec![1, 2, 3]; "with vector")]
72 fn test_ref<T: Clone + PartialEq + Debug>(value: T) {
73 let r_bor = Ref::Borrow(&value);
74 assert_eq!(*r_bor, value);
75
76 let r_own = Ref::Owned(value.clone());
77 assert_eq!(*r_own, value);
78
79 let refcell = RefCell::new(value.clone());
80 let r_ref = Ref::Ref(refcell.borrow());
81 assert_eq!(*r_ref, value);
82
83 let rwlock = RwLock::new(value.clone());
84 let r_rw = Ref::ReadGuard(rwlock.read().unwrap());
85 assert_eq!(*r_rw, value);
86 }
87
88 #[test]
92 fn test_ref_size() {
93 const SIZE: usize = 24;
94
95 assert_eq!(size_of::<Ref<'_, u8>>(), SIZE);
96 }
97}