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}