pipe_chain/pipe/wrap.rs
1use crate::{Pipe, Result};
2use std::marker::PhantomData;
3/// Wraps the pipe and input/ouput into a closure
4pub trait WrapExt<I, O, E, R> {
5 /// wraps self into a function
6 /// ```rust
7 /// # use pipe_chain::{str::TagStrError, tag, AndExt, Incomplete, Pipe, WrapExt, Result};
8 /// # use std::error::Error as StdError;
9 /// # #[derive(Debug, PartialEq, Eq)]
10 /// # enum Error {
11 /// # Tag(TagStrError),
12 /// # Incomplete(Incomplete),
13 /// # }
14 /// #
15 /// # impl std::fmt::Display for Error {
16 /// # fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17 /// # write!(f, "{self:?}")
18 /// # }
19 /// # }
20 /// # impl StdError for Error {}
21 /// #
22 /// # impl From<Incomplete> for Error {
23 /// # fn from(value: Incomplete) -> Error { Error::Incomplete(value) }
24 /// # }
25 /// #
26 /// # impl From<TagStrError> for Error {
27 /// # fn from(value: TagStrError) -> Error { Error::Tag(value) }
28 /// # }
29 /// #
30 /// pub fn input_offset<'a, O, E>(
31 /// p: &mut impl Pipe<&'a str, O, E>, input: (&'a str, usize),
32 /// ) -> Result<(&'a str, usize), O, E> {
33 /// let (i, o) = p.apply(input.0)?;
34 /// Ok(((i, input.1 + (input.0.len() - i.len())), o))
35 /// }
36 /// assert_eq!(
37 /// tag::<Error, _, _>("foo").and(tag("bar")).wrap(input_offset).apply(("foobar", 0)),
38 /// Ok((("", 6), ("foo", "bar")))
39 /// );
40 /// assert_eq!(
41 /// tag::<Error, _, _>("foo").and(tag("bar")).wrap(input_offset).apply(("foobar", 0)),
42 /// Ok((("", 6), ("foo", "bar")))
43 /// );
44 /// ```
45 fn wrap<I2, O2, R2, F>(self, f: F) -> Wrap<I, O, R, Self, F>
46 where
47 Self: Pipe<I, O, E, R> + Sized,
48 F: FnMut(&mut Self, I2) -> Result<R2, O2, E>,
49 {
50 Wrap::new(self, f)
51 }
52}
53
54impl<I, O, E, R, P: Pipe<I, O, E, R>> WrapExt<I, O, E, R> for P {}
55
56/// [WrapExt::wrap] implementation
57pub struct Wrap<I, O, R, P, F>(P, F, PhantomData<I>, PhantomData<O>, PhantomData<R>);
58
59impl<I, O, R, P, F> Wrap<I, O, R, P, F> {
60 fn new(p: P, f: F) -> Self { Self(p, f, PhantomData, PhantomData, PhantomData) }
61}
62
63impl<I, O, E, R, I2, O2, R2, P, F> Pipe<I2, O2, E, R2> for Wrap<I, O, R, P, F>
64where
65 P: Pipe<I, O, E, R>,
66 F: FnMut(&mut P, I2) -> Result<R2, O2, E>,
67{
68 fn apply(&mut self, input: I2) -> Result<R2, O2, E> { (self.1)(&mut self.0, input) }
69}