use super::functions::*;
use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
#[allow(dead_code)]
pub struct LazyResultCell<T, E> {
thunk: Box<dyn Fn() -> std::result::Result<T, E>>,
evaluated: bool,
label: String,
}
#[derive(Clone, Debug, Default)]
pub struct ErrorAccumulator {
errors: Vec<String>,
}
impl ErrorAccumulator {
pub fn new() -> Self {
Self::default()
}
pub fn try_add<T>(&mut self, result: std::result::Result<T, String>) -> Option<T> {
match result {
Ok(v) => Some(v),
Err(e) => {
self.errors.push(e);
None
}
}
}
pub fn has_errors(&self) -> bool {
!self.errors.is_empty()
}
pub fn errors(&self) -> &[String] {
&self.errors
}
pub fn into_result(self) -> std::result::Result<(), String> {
if self.errors.is_empty() {
Ok(())
} else {
Err(self.errors.join("; "))
}
}
pub fn len(&self) -> usize {
self.errors.len()
}
pub fn is_empty(&self) -> bool {
self.errors.is_empty()
}
pub fn clear(&mut self) {
self.errors.clear();
}
}
#[derive(Clone, Debug, Default)]
pub struct ResultRegistry {
registered: Vec<String>,
}
impl ResultRegistry {
pub fn new() -> Self {
Self::default()
}
pub fn register(&mut self, name: impl Into<String>) {
let n = name.into();
if !self.registered.contains(&n) {
self.registered.push(n);
}
}
pub fn contains(&self, name: &str) -> bool {
self.registered.iter().any(|n| n == name)
}
pub fn from_env(env: &Environment) -> Self {
let names = [
"Result",
"Result.ok",
"Result.err",
"Result.isOk",
"Result.isErr",
"Result.map",
"Result.andThen",
"Result.mapErr",
"Result.getOrElse",
"Result.ok_isOk",
"Result.err_isErr",
];
let mut reg = Self::new();
for name in &names {
if env.get(&Name::str(*name)).is_some() {
reg.register(*name);
}
}
reg
}
pub fn all_names(&self) -> &[String] {
&self.registered
}
pub fn len(&self) -> usize {
self.registered.len()
}
pub fn is_empty(&self) -> bool {
self.registered.is_empty()
}
}
#[allow(dead_code)]
pub struct ResultChain<T, E> {
steps: Vec<Box<dyn Fn(T) -> std::result::Result<T, E>>>,
label: String,
}
#[allow(dead_code)]
pub struct ValidationCollector<T, E> {
successes: Vec<T>,
failures: Vec<E>,
capacity: usize,
}
impl<T, E> ValidationCollector<T, E> {
#[allow(dead_code)]
pub fn with_capacity(capacity: usize) -> Self {
Self {
successes: Vec::with_capacity(capacity),
failures: Vec::new(),
capacity,
}
}
#[allow(dead_code)]
pub fn push(&mut self, result: std::result::Result<T, E>) {
match result {
Ok(v) => self.successes.push(v),
Err(e) => self.failures.push(e),
}
}
#[allow(dead_code)]
pub fn is_valid(&self) -> bool {
self.failures.is_empty()
}
#[allow(dead_code)]
pub fn finish(self) -> std::result::Result<Vec<T>, Vec<E>> {
if self.failures.is_empty() {
Ok(self.successes)
} else {
Err(self.failures)
}
}
}
#[allow(dead_code)]
pub struct ResultAxiomRegistry {
names: Vec<String>,
version: u32,
checksum: u64,
}
impl ResultAxiomRegistry {
#[allow(dead_code)]
pub fn new() -> Self {
Self {
names: Vec::new(),
version: 1,
checksum: 0,
}
}
#[allow(dead_code)]
pub fn register(&mut self, name: impl Into<String>) {
let n = name.into();
self.checksum = self.checksum.wrapping_add(n.len() as u64);
self.names.push(n);
}
#[allow(dead_code)]
pub fn len(&self) -> usize {
self.names.len()
}
#[allow(dead_code)]
pub fn is_empty(&self) -> bool {
self.names.is_empty()
}
}
#[allow(dead_code)]
pub struct ResultEitherBridge {
pub convention: &'static str,
pub flip_convention: bool,
pub tag: u8,
}
impl ResultEitherBridge {
#[allow(dead_code)]
pub fn standard() -> Self {
Self {
convention: "Right=Ok, Left=Err",
flip_convention: false,
tag: 0,
}
}
#[allow(dead_code)]
pub fn flipped() -> Self {
Self {
convention: "Left=Ok, Right=Err",
flip_convention: true,
tag: 1,
}
}
#[allow(dead_code)]
pub fn describe(&self) -> &'static str {
self.convention
}
}