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
|
||||
|
||||
pub trait Combinable {
|
||||
/// Evaluates the [Combinable], and returns whether it is alright
|
||||
/// The core trait of Lerox, [Combinator], generically implements a handful of simple
|
||||
/// 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;
|
||||
/// 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)
|
||||
fn and(self, f: impl Fn(Self) -> Self) -> Self {
|
||||
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 {
|
||||
match self.is_alright() {
|
||||
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
|
||||
fn and_maybe(self, f: impl Fn(Self) -> Self) -> Self
|
||||
where Self: Clone {
|
||||
@ -35,21 +59,4 @@ pub trait Combinator: Combinable + Sized {
|
||||
where Self: Clone {
|
||||
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 {
|
||||
self.is_alright
|
||||
}
|
||||
fn alright(self) -> Self {
|
||||
fn into_alright(self) -> Self {
|
||||
Self { is_alright: true, ..self }
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user