neure/re/ctor/
map.rs

1use std::fmt::Debug;
2use std::marker::PhantomData;
3
4use crate::ctx::Context;
5use crate::ctx::Match;
6use crate::ctx::Span;
7use crate::err::Error;
8use crate::map::MapSingle;
9use crate::re::def_not;
10use crate::re::Ctor;
11use crate::re::Extract;
12use crate::re::Handler;
13use crate::re::Regex;
14
15///
16/// Map the result to another type.
17///
18/// # Example 1
19///
20/// ```
21/// # use neure::{err::Error, prelude::*};
22/// #
23/// # fn main() -> color_eyre::Result<()> {
24/// #     color_eyre::install()?;
25///     let str = neu::ascii_alphabetic()
26///         .repeat_times::<3>()
27///         // map &str to String
28///         .map(|v: &str| Ok(String::from(v)));
29///     let num = neu::digit(10)
30///         .repeat_times::<3>()
31///         // map &str to i32
32///         .map(|v: &str| v.parse::<i32>().map_err(|_| Error::Uid(0)));
33///     let (who, id) = CharsCtx::new("foo777").ctor(&str.then(num))?;
34///
35///     assert_eq!(who, "foo");
36///     assert_eq!(id, 777);
37///
38///     Ok(())
39/// # }
40/// ```
41///
42/// # Exampl 2
43///
44/// ```
45/// # use neure::{err::Error, prelude::*};
46/// #
47/// # fn main() -> color_eyre::Result<()> {
48/// #     color_eyre::install()?;
49///     let str = neu::ascii_alphabetic()
50///         .repeat_times::<3>()
51///         // map &str to String
52///         .map(|v: (Span, _)| Ok(v));
53///     let num = neu::digit(10)
54///         .repeat_times::<3>()
55///         // map &str to i32
56///         .map(|(span, v): (Span, &str)| Ok((span, v.parse::<i32>().map_err(|_| Error::Uid(0))?)));
57///     let (who, id) = // you can pass the Span to callback of map
58///         CharsCtx::new("foo777").ctor_with(&str.then(num), &mut |span: Span, v: _| Ok((span, v)))?;
59///
60///     assert_eq!(who, (Span::new(0, 3), "foo"));
61///     assert_eq!(id, (Span::new(3, 3), 777));
62///
63///     Ok(())
64/// # }
65/// ```
66///
67/// # Example 3
68///
69/// ```
70/// # use neure::{err::Error, prelude::*};
71/// #
72/// # fn main() -> color_eyre::Result<()> {
73/// #     color_eyre::install()?;
74///     let num = neu::digit(10).repeat_times::<3>();
75///     let id =
76///         CharsCtx::new("777").map(&num, |v: &str| v.parse::<i32>().map_err(|_| Error::Uid(0)))?;
77///
78///     assert_eq!(id, 777);
79///
80///     let (span, id) = CharsCtx::new("777").map_with(&num, |v: &str, span: Span| {
81///         Ok((span, v.parse::<i32>().map_err(|_| Error::Uid(0))?))
82///     })?;
83///
84///     assert_eq!(id, 777);
85///     assert_eq!(span, Span::new(0, 3));
86///
87///     Ok(())
88/// # }
89/// ```
90#[derive(Default, Copy)]
91pub struct Map<C, P, F, O> {
92    pat: P,
93    mapper: F,
94    marker: PhantomData<(C, O)>,
95}
96
97def_not!(Map<C, P, F, O>);
98
99impl<C, P, F, O> Debug for Map<C, P, F, O>
100where
101    P: Debug,
102    F: Debug,
103{
104    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105        f.debug_struct("Map")
106            .field("pat", &self.pat)
107            .field("mapper", &self.mapper)
108            .finish()
109    }
110}
111
112impl<C, P, F, O> Clone for Map<C, P, F, O>
113where
114    P: Clone,
115    F: Clone,
116{
117    fn clone(&self) -> Self {
118        Self {
119            pat: self.pat.clone(),
120            mapper: self.mapper.clone(),
121            marker: self.marker,
122        }
123    }
124}
125
126impl<C, P, F, O> Map<C, P, F, O> {
127    pub fn new(pat: P, func: F) -> Self {
128        Self {
129            pat,
130            mapper: func,
131            marker: PhantomData,
132        }
133    }
134
135    pub fn pat(&self) -> &P {
136        &self.pat
137    }
138
139    pub fn mapper(&self) -> &F {
140        &self.mapper
141    }
142
143    pub fn pat_mut(&mut self) -> &mut P {
144        &mut self.pat
145    }
146
147    pub fn mapper_mut(&mut self) -> &mut F {
148        &mut self.mapper
149    }
150
151    pub fn set_pat(&mut self, pat: P) -> &mut Self {
152        self.pat = pat;
153        self
154    }
155
156    pub fn set_mapper(&mut self, func: F) -> &mut Self {
157        self.mapper = func;
158        self
159    }
160
161    pub fn map_to<H, V>(self, mapper: H) -> Map<C, P, H, O>
162    where
163        H: MapSingle<O, V>,
164    {
165        Map {
166            pat: self.pat,
167            mapper,
168            marker: self.marker,
169        }
170    }
171}
172
173impl<'a, C, M, O, V, P, F, H, A> Ctor<'a, C, M, V, H, A> for Map<C, P, F, O>
174where
175    P: Ctor<'a, C, M, O, H, A>,
176    F: MapSingle<O, V>,
177    C: Context<'a> + Match<C>,
178    H: Handler<A, Out = M, Error = Error>,
179    A: Extract<'a, C, Span, Out<'a> = A, Error = Error>,
180{
181    #[inline(always)]
182    fn construct(&self, ctx: &mut C, func: &mut H) -> Result<V, Error> {
183        self.mapper.map_to(self.pat.construct(ctx, func)?)
184    }
185}
186
187impl<'a, C, P, F, O> Regex<C> for Map<C, P, F, O>
188where
189    P: Regex<C, Ret = Span>,
190    C: Context<'a> + Match<C>,
191{
192    type Ret = P::Ret;
193
194    #[inline(always)]
195    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
196        ctx.try_mat(&self.pat)
197    }
198}