Skip to main content

wp_primitives/
utils.rs

1use crate::scope::ScopeEval;
2use crate::symbol::ctx_desc;
3use std::fmt::Display;
4use winnow::ModalResult as WResult;
5use winnow::Parser;
6use winnow::ascii::multispace0;
7use winnow::combinator::{fail, peek};
8use winnow::error::{AddContext, ContextError};
9use winnow::stream::{Checkpoint, Stream};
10use winnow::token::take;
11
12pub fn get_scope<'a>(data: &mut &'a str, beg: char, end: char) -> WResult<&'a str> {
13    use winnow::token::{any, take};
14
15    multispace0.parse_next(data)?;
16    let extend_len = ScopeEval::len(data, beg, end);
17    if extend_len < 2 {
18        return fail.context(ctx_desc("scope len <2 ")).parse_next(data);
19    }
20
21    // Use any() to parse a single char instead of converting to string
22    any.verify(|&c| c == beg).parse_next(data)?;
23    let group = take(extend_len - 2).parse_next(data)?;
24    any.verify(|&c| c == end).parse_next(data)?;
25    multispace0(data)?;
26    Ok(group)
27}
28
29pub fn peek_one<'a>(data: &mut &'a str) -> WResult<&'a str> {
30    peek(take(1usize)).parse_next(data)
31}
32
33pub trait RestAble {
34    fn err_reset<'a>(self, data: &mut &'a str, point: &Checkpoint<&'a str, &'a str>) -> Self;
35}
36
37impl<T, E> RestAble for Result<T, E> {
38    fn err_reset<'a>(self, data: &mut &'a str, point: &Checkpoint<&'a str, &'a str>) -> Self {
39        if self.is_err() {
40            data.reset(point);
41        }
42        self
43    }
44}
45
46pub fn err_convert<T, E: Display>(result: Result<T, E>, msg: &'static str) -> WResult<T> {
47    match result {
48        Ok(obj) => Ok(obj),
49        Err(_e) => fail.context(ctx_desc(msg)).parse_next(&mut ""),
50    }
51}
52
53pub fn context_error(
54    input: &str,
55    start: &Checkpoint<&str, &str>,
56    desc: &'static str,
57) -> ContextError {
58    let context = ContextError::default();
59    context.add_context(&input, start, ctx_desc(desc))
60}