Skip to content

Commit

Permalink
on_input
Browse files Browse the repository at this point in the history
  • Loading branch information
Geal committed Nov 1, 2023
1 parent cfe50fa commit cc7f338
Showing 1 changed file with 176 additions and 11 deletions.
187 changes: 176 additions & 11 deletions src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use core::{
any::{Any, TypeId},

Check warning on line 4 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable, --no-default-features --features "alloc")

unused imports: `Any`, `cell::RefCell`

Check warning on line 4 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, --no-default-features)

unused imports: `Any`, `cell::RefCell`

Check warning on line 4 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, --no-default-features --features "alloc")

unused imports: `Any`, `cell::RefCell`

Check warning on line 4 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable, --no-default-features)

unused imports: `Any`, `cell::RefCell`

Check warning on line 4 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable, --no-default-features)

unused imports: `Any`, `cell::RefCell`

Check warning on line 4 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, --no-default-features)

unused imports: `Any`, `cell::RefCell`

Check warning on line 4 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable, --no-default-features --features "alloc")

unused imports: `Any`, `cell::RefCell`

Check warning on line 4 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, --no-default-features --features "alloc")

unused imports: `Any`, `cell::RefCell`
cell::RefCell,
marker::PhantomData,
ops::ControlFlow,
};
use std::{collections::HashMap, thread_local};

Check failure on line 9 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable, --no-default-features --features "alloc")

failed to resolve: use of undeclared crate or module `std`

Check failure on line 9 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable, --no-default-features --features "alloc")

unresolved import `std`

Check failure on line 9 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, --no-default-features)

failed to resolve: use of undeclared crate or module `std`

Check failure on line 9 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, --no-default-features)

unresolved import `std`

Check failure on line 9 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, --no-default-features --features "alloc")

failed to resolve: use of undeclared crate or module `std`

Check failure on line 9 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, --no-default-features --features "alloc")

unresolved import `std`

Check failure on line 9 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable, --no-default-features)

failed to resolve: use of undeclared crate or module `std`

Check failure on line 9 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable, --no-default-features)

unresolved import `std`

Check failure on line 9 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable, --no-default-features)

failed to resolve: use of undeclared crate or module `std`

Check failure on line 9 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable, --no-default-features)

unresolved import `std`

Check failure on line 9 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, --no-default-features)

failed to resolve: use of undeclared crate or module `std`

Check failure on line 9 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, --no-default-features)

unresolved import `std`

Check failure on line 9 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable, --no-default-features --features "alloc")

failed to resolve: use of undeclared crate or module `std`

Check failure on line 9 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable, --no-default-features --features "alloc")

unresolved import `std`

Check failure on line 9 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, --no-default-features --features "alloc")

failed to resolve: use of undeclared crate or module `std`

Check failure on line 9 in src/state/mod.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, --no-default-features --features "alloc")

unresolved import `std`
Expand All @@ -14,7 +15,7 @@ thread_local!(
);

/// TODO
pub struct State<T: 'static, F> {
pub struct InitialState<T: 'static, F> {
initial: T,
parser: F,
}
Expand All @@ -27,7 +28,7 @@ pub fn state<I, E: ParseError<I>, F, T: Clone + 'static>(
where
F: Parser<I, Error = E>,
{
let state = State {
let state = InitialState {
initial: initial_state.clone(),
parser,
};
Expand All @@ -36,21 +37,133 @@ where
}

///on input
pub fn on_input<T: Clone + 'static, I, E: ParseError<I>, F, G>(
pub fn on_input<T: Clone + 'static, I, F, G>(
mut parser: F,
mut map: G,
) -> impl Parser<I, Output = <F as Parser<I>>::Output, Error = E>
) -> impl Parser<I, Output = <F as Parser<I>>::Output, Error = <F as Parser<I>>::Error>
where
F: Parser<I, Error = E>,
G: FnMut(&mut T, I) -> ControlFlow<IResult<I, <F as Parser<I>>::Output, E>, I>,
F: Parser<I>,
G: FnMut(
&mut T,
I,
) -> ControlFlow<IResult<I, <F as Parser<I>>::Output, <F as Parser<I>>::Error>, I>,
{
move |input: I| match State::<T, F>::update_input(&mut map, input) {
move |input: I| match InitialState::<T, F>::update_input(&mut map, input) {
ControlFlow::Continue(i) => parser.parse(i),
ControlFlow::Break(result) => result,
}
}

impl<T: Clone + 'static, F> State<T, F> {
fn st<State, Input, P>(input: Input, parser: P) -> StateParser<State, P>
//impl Parser<Input, Output = <P as Parser<Input>>::Output, Error = <P as Parser<Input>>::Error>
where
P: Parser<Input>,
{
StateParser {
parser,
st: PhantomData,
}
}

struct StateParser<State, P> {
parser: P,
st: PhantomData<State>,
}

impl<State, Input, P> Parser<Input> for StateParser<State, P>
where
P: Parser<Input>,
{
type Output = <P as Parser<Input>>::Output;

type Error = <P as Parser<Input>>::Error;

fn process<OM: OutputMode>(
&mut self,
input: Input,
) -> PResult<OM, Input, Self::Output, Self::Error> {
todo!()
}
}

/*
fn st2<State, Input, F, O, E>(f: F) -> impl Parser<Input, Output = O, Error = E>
where
F: FnMut(State, Input) -> PResult<OM, Input, O, E>,
{
todo!()
}
*/

/*
trait StateTrait<I>: Parser<I> {
fn on_input<T: Clone + 'static, G>(
map: G,
) -> impl Parser<I, Output = <Self as Parser<I>>::Output, Error = <Self as Parser<I>>::Error>
where
G: FnMut(
&mut T,
I,
)
-> ControlFlow<IResult<I, <Self as Parser<I>>::Output, <Self as Parser<I>>::Error>, I>;
}
impl<I, P> StateTrait<I> for P
where
P: Parser<I>,
{
fn on_input<T: Clone + 'static, G>(
mut map: G,
) -> impl Parser<I, Output = <Self as Parser<I>>::Output, Error = <Self as Parser<I>>::Error>
where
G: FnMut(
&mut T,
I,
)
-> ControlFlow<IResult<I, <Self as Parser<I>>::Output, <Self as Parser<I>>::Error>, I>,
{
move |input: I| match InitialState::<T, F>::update_input(&mut map, input) {
ControlFlow::Continue(i) => parser.parse(i),
ControlFlow::Break(result) => result,
}
}
}*/

struct StateInput<State, P, F> {
parser: P,
f: F,
st: PhantomData<State>,
}

impl<State, Input, P, F> Parser<Input> for StateInput<State, P, F>
where
P: Parser<Input>,
F: FnMut(
&mut State,
Input,
) -> ControlFlow<
IResult<Input, <Self as Parser<Input>>::Output, <Self as Parser<Input>>::Error>,
Input,
>,
{
type Output = <P as Parser<Input>>::Output;

type Error = <P as Parser<Input>>::Error;

fn process<OM: OutputMode>(
&mut self,
input: Input,
) -> PResult<OM, Input, Self::Output, Self::Error> {
match InitialState::<State, F>::update_input(&mut self.f, input) {
ControlFlow::Continue(i) => self
.parser
.process::<OutputM<OM::Output, OM::Error, OM::Incomplete>>(i),
ControlFlow::Break(result) => result,
}
}
}

impl<T: Clone + 'static, F> InitialState<T, F> {
fn update_input<G, Res, Input>(mut fun: G, input: Input) -> Res
where
G: FnMut(&mut T, Input) -> Res,
Expand All @@ -72,7 +185,7 @@ impl<T: Clone + 'static, F> State<T, F> {
}
}

impl<I, F, T: Clone + 'static> Parser<I> for State<T, F>
impl<I, F, T: Clone + 'static> Parser<I> for InitialState<T, F>
where
F: Parser<I>,
{
Expand All @@ -94,6 +207,33 @@ where
}
}
}
/*
struct StateParser<F> {
fun: F,
}
impl<I, F, State> Parser<I> for StateParser<F>
where
F: FnMut(State, I) -> Parser<I>,
{
type Output = <F as Parser<I>>::Output;
type Error = <F as Parser<I>>::Error;
#[inline(always)]
fn process<OM: OutputMode>(&mut self, input: I) -> PResult<OM, I, Self::Output, Self::Error> {
self.reset();
match self
.parser
.process::<OutputM<OM::Output, OM::Error, OM::Incomplete>>(input)
{
Err(Err::Error(e)) => Err(Err::Error(e)),
Err(Err::Failure(e)) => Err(Err::Failure(e)),
Err(Err::Incomplete(i)) => Err(Err::Incomplete(i)),
Ok((i, o)) => Ok((i, o)),
}
}
}*/

#[cfg(test)]
mod tests {
Expand All @@ -104,7 +244,7 @@ mod tests {
#[test]
fn state_update() {
fn a(i: &str) -> IResult<&str, &str, ()> {
on_input::<u8, &str, _, _, _>(preceded(tag("a"), b), |state, input| {
on_input::<u8, &str, _, _>(preceded(tag("a"), b), |state, input| {
if *state == 3 {
ControlFlow::Break(Err(Err::Failure(())))
} else {
Expand All @@ -127,5 +267,30 @@ mod tests {
}

#[test]
fn multistate() {}
fn multistate() {
//fn a(i: &str) -> IResult<&str, &str, ()> {
/*
st(|state| {
if state.is_valid() {
preceded(tag("a"), b).map(|o|
//NO! double mutable borrow state.update())
}
})
preceded(tag("a"), b)
.on_input(|state, input| -> ControlFlow)
.on_output(|state, result| -> result)
*/

/*on_input::<u8, &str, _, _, _>(preceded(tag("a"), b), |state, input| {
if *state == 3 {
ControlFlow::Break(Err(Err::Failure(())))
} else {
*state += 1;
ControlFlow::Continue(input)
}
})
.parse(i)*/
//}
}
}

0 comments on commit cc7f338

Please sign in to comment.