1use std::{ops::{BitAnd, BitOr, BitXor}, sync::Arc};
2
3pub trait RawPipeline<VT, RT, ET> {
4 fn run(&self,value: VT) -> Result<RT, ET>;
5}
6pub struct Pipeline<VT, RT, ET> {
7 raw: Arc<dyn RawPipeline<VT, RT, ET> + Sync + Send + 'static>,
8}
9
10impl<VT,RT,ET> Pipeline<VT,RT,ET> {
11 pub fn new<EfffectorT: RawPipeline<VT,RT,ET> + Sync + Send + 'static>(raw: EfffectorT) -> Pipeline<VT,RT,ET> {
12 return Pipeline{
13 raw: Arc::new(raw)
14 };
15 }
16}
17
18impl<VT,RT,ET> Clone for Pipeline<VT,RT,ET> {
19 fn clone(&self) -> Self {
20 Self { raw: self.raw.clone() }
21 }
22}
23
24impl<VT,RT,ET> RawPipeline<VT,RT,ET> for Pipeline<VT,RT,ET> {
25 fn run(&self,value: VT) -> Result<RT, ET> {
26 self.raw.run(value)
27 }
28}
29
30impl<VT: 'static, RT: 'static, ET: 'static> BitAnd<Pipeline<VT,RT,ET>> for Result<VT,ET> {
31 type Output = Result<RT,ET>;
32
33 fn bitand(self, rhs: Pipeline<VT,RT,ET>) -> Self::Output {
34 match self {
35 Ok(v) => rhs.run(v),
36 Err(e) => Err(e),
37 }
38 }
39}
40
41struct AndPipeline<VT, MT, RT, ET> {
42 lhs: Pipeline<VT, MT, ET>,
43 rhs: Pipeline<MT, RT, ET>
44}
45
46impl<VT: 'static, MT: 'static, RT: 'static, ET: 'static> RawPipeline<VT,RT,ET> for AndPipeline<VT,MT,RT,ET> {
47 fn run(&self,value: VT) -> Result<RT, ET> {
48 match self.lhs.run(value) {
49 Ok(v) => self.rhs.run(v),
50 Err(e) => Err(e),
51 }
52 }
53}
54
55impl<VT: 'static, MT:'static, RT: 'static, ET: 'static> BitAnd<Pipeline<MT,RT,ET>> for Pipeline<VT,MT,ET> {
56 type Output = Pipeline<VT,RT,ET>;
57
58 fn bitand(self, rhs: Pipeline<MT,RT,ET>) -> Self::Output {
59 Pipeline::new(AndPipeline {
60 lhs: self,
61 rhs
62 })
63 }
64}
65
66struct OrPipeline<VT, RT, ET> {
67 lhs: Pipeline<VT, RT, ET>,
68 rhs: Pipeline<VT, RT, ET>
69}
70
71impl<VT: Clone + 'static, RT: 'static, ET: 'static> RawPipeline<VT,RT,ET> for OrPipeline<VT,RT,ET> {
72 fn run(&self,value: VT) -> Result<RT, ET> {
73 match self.lhs.run(value.clone()) {
74 Ok(v) => Ok(v),
75 Err(_) => self.rhs.run(value.clone()),
76 }
77 }
78}
79
80impl<VT: Clone + 'static, RT: 'static, ET: 'static> BitOr<Pipeline<VT,RT,ET>> for Pipeline<VT,RT,ET> {
81 type Output = Pipeline<VT,RT,ET>;
82
83 fn bitor(self, rhs: Pipeline<VT,RT,ET>) -> Self::Output {
84 Pipeline::new(OrPipeline {
85 lhs: self,
86 rhs
87 })
88 }
89}
90
91struct SimplePipeline<VT, RT, ET> {
92 raw: Arc<dyn Fn(VT) -> Result<RT, ET> + Sync + Send + 'static>
93}
94
95impl<VT, RT, ET> RawPipeline<VT,RT, ET> for SimplePipeline<VT, RT, ET> {
96 fn run(&self,value: VT) -> Result<RT, ET> {
97 (self.raw)(value)
98 }
99}
100
101pub fn pipeline<VT: 'static, RT: 'static, ET: 'static, F: Fn(VT) -> Result<RT, ET> + Sync + Send + 'static>(f : F) -> Pipeline<VT,RT,ET> {
102 return Pipeline::new(SimplePipeline{
103 raw: Arc::new(f),
104 });
105}
106
107struct FilterPipeline<VT,ET: 'static> {
108 raw: Arc<dyn Fn(&VT) -> bool + Sync + Send + 'static>,
109 error: ET
110}
111
112impl<VT,ET : Clone> RawPipeline<VT,VT,ET> for FilterPipeline<VT,ET> {
113 fn run(&self,v: VT) -> Result<VT, ET> {
114 if (self.raw)(&v) {
115 Ok(v)
116 } else {
117 Err(self.error.clone())
118 }
119 }
120}
121
122pub fn filter<T: 'static, ET: Clone + Sync + Send + 'static, F: Fn(&T) -> bool + Sync + Send + 'static>(f: F, error: ET) -> Pipeline<T, T, ET> {
123 return Pipeline::new(FilterPipeline {
124 raw: Arc::new(f),
125 error
126 });
127}
128
129pub trait RawFramework<VT,RT,ET> {
130 fn run(&self, pipeline: Pipeline<VT,RT,ET>);
131}
132
133pub struct Framework<VT,RT,ET> {
134 raw: Arc<dyn RawFramework<VT,RT,ET>>
135}
136
137impl<VT,RT,ET> Framework<VT,RT,ET> {
138 pub fn new<FT: RawFramework<VT,RT,ET> + 'static>(f: FT) -> Framework<VT, RT, ET> {
139 Framework {
140 raw: Arc::new(f)
141 }
142 }
143}
144
145impl<VT,RT,ET> RawFramework<VT,RT,ET> for Framework<VT,RT,ET> {
146 fn run(&self, pipeline: Pipeline<VT,RT,ET>) {
147 self.raw.run(pipeline)
148 }
149}
150
151impl<VT,RT,ET> BitXor<Framework<VT,RT,ET>> for Pipeline<VT,RT,ET> {
152 type Output = ();
153
154 fn bitxor(self, rhs: Framework<VT,RT,ET>) -> Self::Output {
155 rhs.run(self)
156 }
157}
158
159impl<VT,RT,ET> BitXor<Pipeline<VT,RT,ET>> for Framework<VT,RT,ET> {
160 type Output = ();
161
162 fn bitxor(self, rhs: Pipeline<VT,RT,ET>) -> Self::Output {
163 self.run(rhs)
164 }
165}
166
167struct SimpleFramework<VT,RT,ET> {
168 raw: Arc<dyn Fn(Pipeline<VT,RT,ET>) -> ()>
169}
170
171impl<VT,RT,ET> RawFramework<VT,RT,ET> for SimpleFramework<VT,RT,ET> {
172 fn run(&self, pipeline: Pipeline<VT,RT,ET>) {
173 (self.raw)(pipeline)
174 }
175}
176
177pub fn framework<VT: 'static,RT: 'static,ET: 'static,FT: Fn(Pipeline<VT,RT,ET>) -> () + 'static>(f: FT) -> Framework<VT,RT,ET> {
178 Framework::new(SimpleFramework {
179 raw: Arc::new(f)
180 })
181}
182