lerox: Consolidate traits
The auto-implementation scheme doesn't really fit the application
This commit is contained in:
parent
8bc32896c9
commit
71053f1992
@ -1,13 +1,22 @@
|
|||||||
//! Lerox is a stupid, simple combinator library, part of the Conlang project
|
//! Lerox is a stupid, simple combinator library, part of the Conlang project
|
||||||
|
|
||||||
pub trait Combinable {
|
/// The core trait of Lerox, [Combinator], generically implements a handful of simple
|
||||||
/// Evaluates the [Combinable], and returns whether it is alright
|
/// combinators for your type based on two required functions:
|
||||||
|
/// - [`is_alright(&self) -> bool`](Combinator::is_alright) performs some unspecified *evaluation*
|
||||||
|
/// on `self`, and returns true if `self` is valid for your problem domain.
|
||||||
|
/// - [`into_alright(self) -> Self`](Combinator::into_alright) performs some unspecified
|
||||||
|
/// *transformation* of `self` into an alright version of `self` (that is, one which satisfies
|
||||||
|
/// [`self.is_alright()`](Combinator::is_alright) == `true`)
|
||||||
|
pub trait Combinator: Sized {
|
||||||
|
/// Evaluates the [Combinator], and returns whether it is alright.
|
||||||
|
///
|
||||||
|
/// This is the basis for [Combinator]'s [and*](Combinator::and())/[or*](Combinator::or())
|
||||||
|
/// behaviors, and is like a generic form of [Option::is_some()] or [Result::is_ok()]
|
||||||
fn is_alright(&self) -> bool;
|
fn is_alright(&self) -> bool;
|
||||||
/// Makes this [Combinable] alright, somehow
|
|
||||||
fn alright(self) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Combinator: Combinable + Sized {
|
/// Does something to make this [Combinator] [alright](Combinator::is_alright())
|
||||||
|
fn into_alright(self) -> Self;
|
||||||
|
|
||||||
/// If self is alright, runs f(self)
|
/// If self is alright, runs f(self)
|
||||||
fn and(self, f: impl Fn(Self) -> Self) -> Self {
|
fn and(self, f: impl Fn(Self) -> Self) -> Self {
|
||||||
match self.is_alright() {
|
match self.is_alright() {
|
||||||
@ -16,14 +25,29 @@ pub trait Combinator: Combinable + Sized {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If self is not alright, runs f(self)
|
/// If self is not alright, runs f(self) as if it were alright
|
||||||
fn or(self, f: impl FnOnce(Self) -> Self) -> Self {
|
fn or(self, f: impl FnOnce(Self) -> Self) -> Self {
|
||||||
match self.is_alright() {
|
match self.is_alright() {
|
||||||
true => self,
|
true => self,
|
||||||
false => f(self),
|
false => f(self.into_alright()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Repeats the function f on self until it would fail
|
||||||
|
fn and_any(self, f: impl Fn(Self) -> Self) -> Self {
|
||||||
|
self.and(|mut this| {
|
||||||
|
while this.is_alright() {
|
||||||
|
this = this.and(&f)
|
||||||
|
}
|
||||||
|
this.into_alright()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Repeats the function f on self at least once, then until it fails.
|
||||||
|
fn and_many(self, f: impl Fn(Self) -> Self) -> Self {
|
||||||
|
self.and(&f).and_any(f)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the result of running f on self, or if it fails, the original self
|
/// Returns the result of running f on self, or if it fails, the original self
|
||||||
fn and_maybe(self, f: impl Fn(Self) -> Self) -> Self
|
fn and_maybe(self, f: impl Fn(Self) -> Self) -> Self
|
||||||
where Self: Clone {
|
where Self: Clone {
|
||||||
@ -35,21 +59,4 @@ pub trait Combinator: Combinable + Sized {
|
|||||||
where Self: Clone {
|
where Self: Clone {
|
||||||
self.clone().and(f).or(|_| g(self))
|
self.clone().and(f).or(|_| g(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Repeats the function f on self until it fails
|
|
||||||
fn and_any(self, f: impl Fn(Self) -> Self) -> Self {
|
|
||||||
self.and(|mut this| {
|
|
||||||
while this.is_alright() {
|
|
||||||
this = this.and(&f)
|
|
||||||
}
|
}
|
||||||
this.alright()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Repeats the function f on self at least once, then until it fails.
|
|
||||||
fn and_many(self, f: impl Fn(Self) -> Self) -> Self {
|
|
||||||
self.and(&f).and_any(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C: Combinable> Combinator for C {}
|
|
||||||
|
@ -133,11 +133,11 @@ pub mod lexer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'t> lerox::Combinable for Rule<'t> {
|
impl<'t> lerox::Combinator for Rule<'t> {
|
||||||
fn is_alright(&self) -> bool {
|
fn is_alright(&self) -> bool {
|
||||||
self.is_alright
|
self.is_alright
|
||||||
}
|
}
|
||||||
fn alright(self) -> Self {
|
fn into_alright(self) -> Self {
|
||||||
Self { is_alright: true, ..self }
|
Self { is_alright: true, ..self }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user