oxilean_std/result/
types.rs1use super::functions::*;
6use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
7
8#[allow(dead_code)]
10pub struct LazyResultCell<T, E> {
11 thunk: Box<dyn Fn() -> std::result::Result<T, E>>,
12 evaluated: bool,
13 label: String,
14}
15#[derive(Clone, Debug, Default)]
19pub struct ErrorAccumulator {
20 errors: Vec<String>,
21}
22impl ErrorAccumulator {
23 pub fn new() -> Self {
25 Self::default()
26 }
27 pub fn try_add<T>(&mut self, result: std::result::Result<T, String>) -> Option<T> {
31 match result {
32 Ok(v) => Some(v),
33 Err(e) => {
34 self.errors.push(e);
35 None
36 }
37 }
38 }
39 pub fn has_errors(&self) -> bool {
41 !self.errors.is_empty()
42 }
43 pub fn errors(&self) -> &[String] {
45 &self.errors
46 }
47 pub fn into_result(self) -> std::result::Result<(), String> {
51 if self.errors.is_empty() {
52 Ok(())
53 } else {
54 Err(self.errors.join("; "))
55 }
56 }
57 pub fn len(&self) -> usize {
59 self.errors.len()
60 }
61 pub fn is_empty(&self) -> bool {
63 self.errors.is_empty()
64 }
65 pub fn clear(&mut self) {
67 self.errors.clear();
68 }
69}
70#[derive(Clone, Debug, Default)]
72pub struct ResultRegistry {
73 registered: Vec<String>,
75}
76impl ResultRegistry {
77 pub fn new() -> Self {
79 Self::default()
80 }
81 pub fn register(&mut self, name: impl Into<String>) {
83 let n = name.into();
84 if !self.registered.contains(&n) {
85 self.registered.push(n);
86 }
87 }
88 pub fn contains(&self, name: &str) -> bool {
90 self.registered.iter().any(|n| n == name)
91 }
92 pub fn from_env(env: &Environment) -> Self {
94 let names = [
95 "Result",
96 "Result.ok",
97 "Result.err",
98 "Result.isOk",
99 "Result.isErr",
100 "Result.map",
101 "Result.andThen",
102 "Result.mapErr",
103 "Result.getOrElse",
104 "Result.ok_isOk",
105 "Result.err_isErr",
106 ];
107 let mut reg = Self::new();
108 for name in &names {
109 if env.get(&Name::str(*name)).is_some() {
110 reg.register(*name);
111 }
112 }
113 reg
114 }
115 pub fn all_names(&self) -> &[String] {
117 &self.registered
118 }
119 pub fn len(&self) -> usize {
121 self.registered.len()
122 }
123 pub fn is_empty(&self) -> bool {
125 self.registered.is_empty()
126 }
127}
128#[allow(dead_code)]
130pub struct ResultChain<T, E> {
131 steps: Vec<Box<dyn Fn(T) -> std::result::Result<T, E>>>,
132 label: String,
133}
134#[allow(dead_code)]
136pub struct ValidationCollector<T, E> {
137 successes: Vec<T>,
138 failures: Vec<E>,
139 capacity: usize,
140}
141impl<T, E> ValidationCollector<T, E> {
142 #[allow(dead_code)]
144 pub fn with_capacity(capacity: usize) -> Self {
145 Self {
146 successes: Vec::with_capacity(capacity),
147 failures: Vec::new(),
148 capacity,
149 }
150 }
151 #[allow(dead_code)]
153 pub fn push(&mut self, result: std::result::Result<T, E>) {
154 match result {
155 Ok(v) => self.successes.push(v),
156 Err(e) => self.failures.push(e),
157 }
158 }
159 #[allow(dead_code)]
161 pub fn is_valid(&self) -> bool {
162 self.failures.is_empty()
163 }
164 #[allow(dead_code)]
166 pub fn finish(self) -> std::result::Result<Vec<T>, Vec<E>> {
167 if self.failures.is_empty() {
168 Ok(self.successes)
169 } else {
170 Err(self.failures)
171 }
172 }
173}
174#[allow(dead_code)]
176pub struct ResultAxiomRegistry {
177 names: Vec<String>,
178 version: u32,
179 checksum: u64,
180}
181impl ResultAxiomRegistry {
182 #[allow(dead_code)]
184 pub fn new() -> Self {
185 Self {
186 names: Vec::new(),
187 version: 1,
188 checksum: 0,
189 }
190 }
191 #[allow(dead_code)]
193 pub fn register(&mut self, name: impl Into<String>) {
194 let n = name.into();
195 self.checksum = self.checksum.wrapping_add(n.len() as u64);
196 self.names.push(n);
197 }
198 #[allow(dead_code)]
200 pub fn len(&self) -> usize {
201 self.names.len()
202 }
203 #[allow(dead_code)]
205 pub fn is_empty(&self) -> bool {
206 self.names.is_empty()
207 }
208}
209#[allow(dead_code)]
211pub struct ResultEitherBridge {
212 pub convention: &'static str,
213 pub flip_convention: bool,
214 pub tag: u8,
215}
216impl ResultEitherBridge {
217 #[allow(dead_code)]
219 pub fn standard() -> Self {
220 Self {
221 convention: "Right=Ok, Left=Err",
222 flip_convention: false,
223 tag: 0,
224 }
225 }
226 #[allow(dead_code)]
228 pub fn flipped() -> Self {
229 Self {
230 convention: "Left=Ok, Right=Err",
231 flip_convention: true,
232 tag: 1,
233 }
234 }
235 #[allow(dead_code)]
237 pub fn describe(&self) -> &'static str {
238 self.convention
239 }
240}