Skip to main content

oxilean_std/result/
types.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use super::functions::*;
6use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
7
8/// A lazily-evaluated Result cell (thunk wrapper).
9#[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/// A simple error accumulator for collecting multiple Result errors.
16///
17/// Useful when you want to collect all errors before reporting them.
18#[derive(Clone, Debug, Default)]
19pub struct ErrorAccumulator {
20    errors: Vec<String>,
21}
22impl ErrorAccumulator {
23    /// Create a new empty accumulator.
24    pub fn new() -> Self {
25        Self::default()
26    }
27    /// Try a Result and accumulate any error.
28    ///
29    /// Returns the value if Ok, or records the error and returns None.
30    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    /// Check if any errors have been accumulated.
40    pub fn has_errors(&self) -> bool {
41        !self.errors.is_empty()
42    }
43    /// Return the accumulated errors.
44    pub fn errors(&self) -> &[String] {
45        &self.errors
46    }
47    /// Convert accumulated errors into a single Result.
48    ///
49    /// Returns `Ok(())` if there are no errors, or `Err(combined_message)` otherwise.
50    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    /// Return the number of accumulated errors.
58    pub fn len(&self) -> usize {
59        self.errors.len()
60    }
61    /// Check if there are no errors.
62    pub fn is_empty(&self) -> bool {
63        self.errors.is_empty()
64    }
65    /// Clear all accumulated errors.
66    pub fn clear(&mut self) {
67        self.errors.clear();
68    }
69}
70/// A registry of Result-related definitions in an environment.
71#[derive(Clone, Debug, Default)]
72pub struct ResultRegistry {
73    /// Names of all Result definitions known to be present.
74    registered: Vec<String>,
75}
76impl ResultRegistry {
77    /// Create an empty registry.
78    pub fn new() -> Self {
79        Self::default()
80    }
81    /// Register a new definition name.
82    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    /// Check if a definition is registered.
89    pub fn contains(&self, name: &str) -> bool {
90        self.registered.iter().any(|n| n == name)
91    }
92    /// Build from an environment by scanning for `Result.*` declarations.
93    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    /// Return all registered names.
116    pub fn all_names(&self) -> &[String] {
117        &self.registered
118    }
119    /// Number of registered definitions.
120    pub fn len(&self) -> usize {
121        self.registered.len()
122    }
123    /// Whether the registry is empty.
124    pub fn is_empty(&self) -> bool {
125        self.registered.is_empty()
126    }
127}
128/// A chain of Result-producing computations (monadic pipeline).
129#[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/// Collects multiple Results, accumulating all errors (Validation-style).
135#[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    /// Create with a capacity hint.
143    #[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    /// Push a Result into the collector.
152    #[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    /// True if there were no failures.
160    #[allow(dead_code)]
161    pub fn is_valid(&self) -> bool {
162        self.failures.is_empty()
163    }
164    /// Consume into a Result of all successes, or all failures.
165    #[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/// Registry tracking which Result extended axioms have been registered.
175#[allow(dead_code)]
176pub struct ResultAxiomRegistry {
177    names: Vec<String>,
178    version: u32,
179    checksum: u64,
180}
181impl ResultAxiomRegistry {
182    /// Create a new empty registry.
183    #[allow(dead_code)]
184    pub fn new() -> Self {
185        Self {
186            names: Vec::new(),
187            version: 1,
188            checksum: 0,
189        }
190    }
191    /// Register a name and update the checksum.
192    #[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    /// Count registered axioms.
199    #[allow(dead_code)]
200    pub fn len(&self) -> usize {
201        self.names.len()
202    }
203    /// Check if empty.
204    #[allow(dead_code)]
205    pub fn is_empty(&self) -> bool {
206        self.names.is_empty()
207    }
208}
209/// Bridge between Result<T,E> and Either<E,T> representations.
210#[allow(dead_code)]
211pub struct ResultEitherBridge {
212    pub convention: &'static str,
213    pub flip_convention: bool,
214    pub tag: u8,
215}
216impl ResultEitherBridge {
217    /// Create a standard Right-is-Ok bridge.
218    #[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    /// Create a flipped Left-is-Ok bridge.
227    #[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    /// Describe the current convention.
236    #[allow(dead_code)]
237    pub fn describe(&self) -> &'static str {
238        self.convention
239    }
240}