From d7bdd477e266864e45ee33b29adba17bf3f70b20 Mon Sep 17 00:00:00 2001 From: gennyble Date: Tue, 29 Apr 2025 14:45:01 -0500 Subject: initial commit --- src/formula.rs | 192 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 src/formula.rs (limited to 'src/formula.rs') diff --git a/src/formula.rs b/src/formula.rs new file mode 100644 index 0000000..3e84015 --- /dev/null +++ b/src/formula.rs @@ -0,0 +1,192 @@ +use core::fmt; +use std::{ + marker::PhantomData, + ops::{Range, RangeBounds, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive}, + path::PathBuf, + str::FromStr, +}; + +pub struct Formula { + pub(crate) check_fn: Option<(String, Box bool>)>, + pub(crate) failure: String, + pub(crate) missing: Option, + phantom: PhantomData, +} + +impl Formula { + pub fn new>(failure: S) -> Self { + Self { + check_fn: None, + failure: failure.into(), + missing: None, + phantom: PhantomData::default(), + } + } + + pub fn check, F>(mut self, fail: S, check: F) -> Self + where + F: FnMut(&T) -> bool + 'static, + { + self.check_fn = Some((fail.into(), Box::new(check))); + self + } + + pub fn required>(mut self, missing: S) -> Self { + self.missing = Some(missing.into()); + self + } +} + +impl From for Formula { + fn from(value: String) -> Self { + Formula::new(value) + } +} + +impl From<&str> for Formula { + fn from(value: &str) -> Self { + Formula::new(value) + } +} + +impl From for Formula { + fn from(value: UsizeFormula) -> Self { + let UsizeFormula { bounds } = value; + let form = Formula::new("Failed to parse [opt] as an integer"); + + if let Some(bounds) = bounds { + let fail = format!("[opt] must be {bounds}"); + + form.check(fail, move |u| bounds.contains(&u)) + } else { + form + } + } +} + +impl From for Formula { + fn from(value: F32Formula) -> Self { + let F32Formula { bounds } = value; + let form = Formula::new("Failed to parse [opt] as a number"); + + if let Some(bounds) = bounds { + let fail = format!("[opt] must be {bounds}"); + + form.check(fail, move |u| bounds.contains(&u)) + } else { + form + } + } +} + +impl From for Formula { + fn from(_value: PathFormula) -> Self { + Formula::new("Failed to parse [opt] as a path") + } +} + +pub struct F32Formula { + bounds: Option>, +} + +impl F32Formula { + pub fn new() -> Self { + Self { bounds: None } + } + + pub fn bounds>>(mut self, bounds: R) -> Self { + self.bounds = Some(bounds.into()); + self + } +} + +pub struct UsizeFormula { + bounds: Option>, +} + +impl UsizeFormula { + pub fn new() -> Self { + Self { bounds: None } + } + + pub fn bounds>>(mut self, bounds: R) -> Self { + self.bounds = Some(bounds.into()); + self + } +} + +pub enum Ranges { + Exlusive(Range), + Inclusive(RangeInclusive), + From(RangeFrom), + To(RangeTo), + ToInclusive(RangeToInclusive), +} + +impl From> for Ranges { + fn from(value: Range) -> Self { + Ranges::Exlusive(value) + } +} + +impl From> for Ranges { + fn from(value: RangeFrom) -> Self { + Ranges::From(value) + } +} + +impl From> for Ranges { + fn from(value: RangeTo) -> Self { + Ranges::To(value) + } +} + +impl From> for Ranges { + fn from(value: RangeInclusive) -> Self { + Ranges::Inclusive(value) + } +} + +impl From> for Ranges { + fn from(value: RangeToInclusive) -> Self { + Ranges::ToInclusive(value) + } +} + +impl fmt::Display for Ranges { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Ranges::Exlusive(range) => { + write!(f, "from {} and less than {}", range.start, range.end) + } + Ranges::Inclusive(range) => write!(f, "from {} to {}", range.start(), range.end()), + Ranges::From(range) => write!(f, "greater than {}", range.start), + Ranges::To(range) => write!(f, "less than {}", range.end), + Ranges::ToInclusive(range) => write!(f, "from 0 to {}", range.end), + } + } +} + +impl Ranges { + pub fn contains(&self, item: &U) -> bool + where + T: PartialOrd, + U: PartialOrd + ?Sized, + { + match self { + Ranges::Exlusive(range) => range.contains(item), + Ranges::Inclusive(range) => range.contains(item), + Ranges::From(range) => range.contains(item), + Ranges::To(range) => range.contains(item), + Ranges::ToInclusive(range) => range.contains(item), + } + } +} + +pub struct PathFormula; + +impl PathFormula { + pub fn new() -> Self { + Self {} + } +} -- cgit 1.4.1-3-g733a5