sfo_split/
split.rs

1use std::ops::{Deref, DerefMut};
2use std::sync::Arc;
3
4pub struct Splittable<R, W> {
5    r: R,
6    w: W,
7}
8
9impl<R, W> Splittable<R, W> {
10    pub fn new(r: R, w: W) -> Self {
11        Self {
12            r,
13            w,
14        }
15    }
16
17    pub fn split(self) -> (RHalf<R, W>, WHalf<R, W>) {
18        let key = Arc::new(0);
19        (
20            RHalf::new(self.r, key.clone()),
21            WHalf::new(self.w, key),
22        )
23    }
24
25    pub fn get_r(&self) -> &R {
26        &self.r
27    }
28
29    pub fn get_w(&self) -> &W {
30        &self.w
31    }
32
33    pub fn get_r_mut(&mut self) -> &mut R {
34        &mut self.r
35    }
36
37    pub fn get_w_mut(&mut self) -> &mut W {
38        &mut self.w
39    }
40}
41
42pub struct RHalf<R, W> {
43    k: Arc<u8>,
44    r: R,
45    _p: std::marker::PhantomData<W>,
46}
47
48impl<R, W> RHalf<R, W> {
49    pub(crate) fn new(r: R, k: Arc<u8>) -> Self {
50        Self {
51            k,
52            r,
53            _p: Default::default(),
54        }
55    }
56
57    pub fn is_pair_of(&self, w: &WHalf<R, W>) -> bool {
58        Arc::ptr_eq(&self.k, &w.k)
59    }
60
61    pub fn unsplit(self, w: WHalf<R, W>) -> Splittable<R, W> {
62        if !self.is_pair_of(&w) {
63            panic!("not a pair");
64        }
65
66        Splittable::new(self.r, w.w)
67    }
68}
69
70impl<R, W> Deref for RHalf<R, W> {
71    type Target = R;
72    fn deref(&self) -> &Self::Target {
73        &self.r
74    }
75}
76
77impl<R, W> DerefMut for RHalf<R, W> {
78    fn deref_mut(&mut self) -> &mut Self::Target {
79        &mut self.r
80    }
81}
82
83pub struct WHalf<R, W> {
84    k: Arc<u8>,
85    w: W,
86    _p: std::marker::PhantomData<R>,
87}
88
89impl<R, W> WHalf<R, W> {
90    pub(crate) fn new(w: W, k: Arc<u8>) -> Self {
91        Self {
92            k,
93            w,
94            _p: Default::default(),
95        }
96    }
97
98    pub fn is_pair_of(&self, r: &RHalf<R, W>) -> bool {
99        r.is_pair_of(self)
100    }
101
102    pub fn unsplit(self, r: RHalf<R, W>) -> Splittable<R, W> {
103        r.unsplit(self)
104    }
105}
106
107impl<R, W> DerefMut for WHalf<R, W> {
108    fn deref_mut(&mut self) -> &mut Self::Target {
109        &mut self.w
110    }
111}
112
113impl<R, W> Deref for WHalf<R, W> {
114    type Target = W;
115    fn deref(&self) -> &Self::Target {
116        &self.w
117    }
118}
119
120#[cfg(test)]
121mod Test {
122    #[test]
123    fn test() {
124        pub struct TestRead {
125
126        }
127
128        pub struct TestWrite {
129
130        }
131
132        let s1 = super::Splittable::new(TestRead{}, TestWrite{});
133        let (r1, w1) = s1.split();
134        let s2 = super::Splittable::new(TestRead{}, TestWrite{});
135        let (r2, w2) = s2.split();
136        assert!(r1.is_pair_of(&w1));
137        assert!(w1.is_pair_of(&r1));
138        assert!(r2.is_pair_of(&w2));
139        assert!(w2.is_pair_of(&r2));
140        assert!(!w1.is_pair_of(&r2));
141        assert!(!w2.is_pair_of(&r1));
142
143        let s1 = r1.unsplit(w1);
144        let s2 = r2.unsplit(w2);
145    }
146}