Struct neure::re::ctor::Collect

source ·
pub struct Collect<C, P, O, V> { /* private fields */ }
Expand description

Repeatedly match the regex P at least min times.

Ctor

Return a type V that collects the result of regex P. Collect will always succeed if the minimum size is 0, be careful to use it with .sep faimly APIs. The default size is 1.

Example

    let re = b'+'.repeat_one().collect::<_, Vec<_>>();

    assert!(BytesCtx::new(b"---A").ctor(&re).is_err());
    assert_eq!(BytesCtx::new(b"+++A").ctor(&re)?, vec![b"+", b"+", b"+"]);
    assert_eq!(BytesCtx::new(b"++-A").ctor(&re)?, vec![b"+", b"+"]);
    Ok(())

Implementations§

source§

impl<C, P, O, V> Collect<C, P, O, V>

source

pub fn new(pat: P) -> Self

source

pub fn pat(&self) -> &P

source

pub fn pat_mut(&mut self) -> &mut P

source

pub fn min(&self) -> usize

source

pub fn set_pat(&mut self, pat: P) -> &mut Self

source

pub fn set_min(&mut self, min: usize) -> &mut Self

source

pub fn at_least(self, min: usize) -> Self

Trait Implementations§

source§

impl<C, P, O, V> Clone for Collect<C, P, O, V>where P: Clone,

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a, C, P, M, O, V> Ctor<'a, C, M, V> for Collect<C, P, O, V>where V: FromIterator<O>, P: Ctor<'a, C, M, O>, C: Context<'a> + Match<C>,

source§

fn constrct<H, A>(&self, ctx: &mut C, func: &mut H) -> Result<V, Error>where H: Handler<A, Out = M, Error = Error>, A: Extract<'a, C, Span, Out<'a> = A, Error = Error>,

source§

impl<C, P, O, V> Debug for Collect<C, P, O, V>where P: Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<C: Default, P: Default, O: Default, V: Default> Default for Collect<C, P, O, V>

source§

fn default() -> Collect<C, P, O, V>

Returns the “default value” for a type. Read more
source§

impl<C, P, O, V> Not for Collect<C, P, O, V>

§

type Output = RegexNot<Collect<C, P, O, V>>

The resulting type after applying the ! operator.
source§

fn not(self) -> Self::Output

Performs the unary ! operation. Read more
source§

impl<'a, C, P, O, V> Regex<C> for Collect<C, P, O, V>where P: Regex<C, Ret = Span>, C: Context<'a> + Match<C>,

§

type Ret = <P as Regex<C>>::Ret

source§

fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error>

source§

fn parse(&self, ctx: &mut C) -> bool

source§

impl<C: Copy, P: Copy, O: Copy, V: Copy> Copy for Collect<C, P, O, V>

Auto Trait Implementations§

§

impl<C, P, O, V> RefUnwindSafe for Collect<C, P, O, V>where C: RefUnwindSafe, O: RefUnwindSafe, P: RefUnwindSafe, V: RefUnwindSafe,

§

impl<C, P, O, V> Send for Collect<C, P, O, V>where C: Send, O: Send, P: Send, V: Send,

§

impl<C, P, O, V> Sync for Collect<C, P, O, V>where C: Sync, O: Sync, P: Sync, V: Sync,

§

impl<C, P, O, V> Unpin for Collect<C, P, O, V>where C: Unpin, O: Unpin, P: Unpin, V: Unpin,

§

impl<C, P, O, V> UnwindSafe for Collect<C, P, O, V>where C: UnwindSafe, O: UnwindSafe, P: UnwindSafe, V: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<'a, C, M, O, I> BoxedCtorHelper<'a, C, M, O> for Iwhere I: Ctor<'a, C, M, O>, C: Context<'a> + Match<C>,

source§

impl<'a, C, T> ConstructOp<'a, C> for Twhere T: Regex<C>, C: Context<'a> + Match<C>,

source§

fn pat(self) -> Pattern<C, T>

Call .try_mat to match regex P.

Example
    let digit = re!(['0' - '9']+);
    let digit = digit.map(|v: &str| Ok(v.parse::<i64>().unwrap()));
    let digits = digit.sep(",".ws());
    let array = digits.quote("[", "]");
    let mut ctx = CharsCtx::new("[2, 4, 8, 16, 42]");

    assert_eq!(ctx.ctor(&array)?, vec![2, 4, 8, 16, 42]);
    assert_eq!(ctx.reset().ctor(&array.pat())?, "[2, 4, 8, 16, 42]");

    Ok(())
source§

fn opt(self) -> OptionPat<C, T>

Match P and return the result wrapped by Option, ignoring the error.

Example
    let num = neu::digit(10)
        .repeat_one_more()
        .map(map::from_str::<usize>())
        .opt();

    assert_eq!(CharsCtx::new("foo").ctor(&num)?, None);
    assert_eq!(CharsCtx::new("955").ctor(&num)?, Some(955));
    Ok(())
source§

fn quote<L, R>(self, left: L, right: R) -> Quote<C, T, L, R>

First try to match L. If it is succeeds, then try to match P. If it is succeeds, then try to match R.

Example
    let ascii = neu::ascii().repeat_one();
    let lit = ascii.quote("'", "'");
    let ele = lit.sep(",".ws());
    let arr = ele.quote("[", "]");
    let mut ctx = CharsCtx::new("['a', 'c', 'd', 'f']");

    assert_eq!(ctx.ctor(&arr)?, ["a", "c", "d", "f"]);

    Ok(())
source§

fn sep<S>(self, sep: S) -> Separate<C, T, S>

Match regex P as many times as possible, with S as the delimiter.

Example
    let name = re!([^ ',' ']' '[']+);
    let sep = ','.repeat_one().ws();
    let arr = name.sep(sep);
    let arr = arr.quote("[", "]");
    let mut ctx = CharsCtx::new(r#"[c, rust, java, c++]"#);

    assert_eq!(ctx.ctor(&arr)?, vec!["c", "rust", "java", "c++"]);
    Ok(())
source§

fn sep_once<S, R>(self, sep: S, right: R) -> SepOnce<C, T, S, R>

Match L and R separated by S.

Example
    let key = neu::alphabetic().repeat_one_more().ws();
    let val = neu::whitespace().or(',').not().repeat_one_more().ws();
    let sep = "=>".ws();
    let ele = key.sep_once(sep, val);
    let hash = ele.sep(",".ws()).quote("{".ws(), "}");
    let mut ctx = CharsCtx::new(
        r#"{
        c => c11,
        cpp => c++23,
        rust => 2021,
    }"#,
    );

    assert_eq!(
        ctx.ctor(&hash)?,
        [("c", "c11"), ("cpp", "c++23"), ("rust", "2021")]
    );
    Ok(())
source§

fn sep_collect<S, O, V>(self, sep: S) -> SepCollect<C, T, S, O, V>

Match regex P as many times as possible, with S as the delimiter.

Example
    let key = neu::alphabetic().repeat_one_more().ws();
    let val = neu::whitespace().or(',').not().repeat_one_more().ws();
    let sep = "=>".ws();
    let ele = key.sep_once(sep, val);
    let hash = ele.sep_collect(",".ws()).quote("{".ws(), "}");
    let mut ctx = CharsCtx::new(
        r#"{
        c => c11,
        cpp => c++23,
        rust => 2021,
    }"#,
    );

    let hash: HashMap<&str, &str> = ctx.ctor(&hash)?;

    assert_eq!(hash.get("c"), Some(&"c11"));
    assert_eq!(hash.get("cpp"), Some(&"c++23"));
    assert_eq!(hash.get("rust"), Some(&"2021"));
    Ok(())
source§

fn or<P>(self, pat: P) -> Or<C, T, P>

First try to match L, if it fails, then try to match R.

Example
    #[derive(Debug, PartialEq, Eq)]
    pub enum V<'a> {
        S(&'a str),
    }

    let cond = neu::re_cond(re::not("\\\""));
    let str = re!([^ '"' ]+).set_cond(cond).or("\\\"").repeat(1..).pat();
    let str = str.quote("\"", "\"");
    let str = str.map(|v| Ok(V::S(v)));
    let vals = str.sep(",".ws());
    let text = r#""lily\"", "lilei", "lucy""#;
    let mut ctx = CharsCtx::new(text);

    assert_eq!(
        ctx.ctor(&vals)?,
        [V::S("lily\\\""), V::S("lilei"), V::S("lucy")]
    );
    Ok(())
source§

fn ltm<P>(self, pat: P) -> LongestTokenMatch<C, T, P>

Match L and R, return the longest match result.

Example
    #[derive(Debug, PartialEq, Eq)]
    pub struct Val<'a>(&'a str);

    let val = "v".ltm("val".ltm("value"));
    let val = val.map(|v| Ok(Val(v)));
    let val = val.sep(",".ws());
    let val = val.quote("{", "}");
    let mut ctx = CharsCtx::new(r#"{val, v, value}"#);

    assert_eq!(ctx.ctor(&val)?, [Val("val"), Val("v"), Val("value")]);
    Ok(())
source§

fn then<P>(self, then: P) -> Then<C, T, P>

First try to match P. If it succeeds, then try to match T.

Example
    let ws = neu::whitespace().repeat_full();
    let id = neu::ascii_alphabetic().repeat_one_more();
    let st = "struct".ws().then(id)._1();
    let en = "enum".ws().then(id)._1();
    let ty = st.or(en);
    let ty = ty.ws().then(ws.quote("{", "}"))._0();
    let mut ctx = CharsCtx::new(r#"struct widget { }"#);

    assert_eq!(ctx.ctor(&ty)?, "widget");
    Ok(())
source§

fn if_then<I, P>(self, if: I, then: P) -> IfThen<C, T, I, P>

First try to match P. If it succeeds, then try to match I. If it succeeds, then try to match T.

Example
    let sp = neu::whitespace().repeat_full();
    let using = "use"
        .sep_once(
            "",
            neu::ascii_alphanumeric()
                .or('*')
                .or('_')
                .repeat_one_more()
                .sep("::"),
        )
        ._1()
        .if_then("as", neu::ascii_alphanumeric().repeat_one_more());

    for (str, res) in [
        (
            "use neure::prelude::*",
            (vec!["neure", "prelude", "*"], None),
        ),
        ("use neure as regex", (vec!["neure"], Some("regex"))),
    ] {
        assert_eq!(CharsCtx::new(str).ignore(sp).ctor(&using)?, res);
    }

    Ok(())
source§

fn repeat(self, range: impl Into<CRange<usize>>) -> Repeat<C, T>

Repeatedly match regex P, and the number of matches must meet the given range.

Example
    let int = neu::digit(10).repeat_one_more();
    let int = int.map(map::from_str_radix::<i32>(10));
    let num = int.ws().repeat(3..5);
    let mut ctx = CharsCtx::new(r#"1 2 3 4"#);

    assert_eq!(ctx.ctor(&num)?, [1, 2, 3, 4]);
    Ok(())
source§

fn collect<O, V>(self) -> Collect<C, T, O, V>

Repeatedly match the regex P at least min times.

Example
    let val = re::consume(2)
        .map(map::from_le_bytes::<i16>())
        .collect::<_, Vec<_>>();

    assert_eq!(
        BytesCtx::new(b"\x2f\0\x1f\0\x0f\0").ctor(&val)?,
        vec![0x2f, 0x1f, 0x0f]
    );

    Ok(())
source§

fn if<I, E>(self, if: I, else: E) -> IfRegex<C, T, I, E>where I: Fn(&C) -> Result<bool, Error>,

Construct a branch struct base on the test I(Fn(&C) -> Result<bool, Error>).

Example
    let val = "file://".r#if(
        // test if it is a file url
        |ctx: &CharsCtx| Ok(ctx.orig()?.starts_with("file")),
        "http://",
    );

    assert_eq!(CharsCtx::new("file://").ctor(&val)?, "file://");
    assert_eq!(CharsCtx::new("http://").ctor(&val)?, "http://");

    Ok(())
source§

fn pad<P>(self, pat: P) -> Pad<C, T, P>

First try to match P. If the match succeeds, then try to match T.

Example
    let sep = neu!([',' ';']);
    let end = neu!(['。' '?' '!']);
    let word = sep.or(end).not().repeat_one_more();
    let sent = word.sep(sep.repeat_one().ws()).pad(end.repeat_one());
    let sent = sent.repeat(1..);
    let mut ctx = CharsCtx::new(
        r#"暖日晴风初破冻。柳眼眉腮,已觉春心动。酒意诗情谁与共。泪融残粉花钿重。乍试夹衫金缕缝。山枕斜敧,枕损钗头凤。独抱浓愁无好梦。夜阑犹剪灯花弄。"#,
    );

    assert_eq!(ctx.ctor(&sent)?.len(), 8);
    Ok(())
source§

fn padded<P>(self, pat: P) -> Padded<C, T, P>

First try to match T. If it succeeds, try to match P.

Example
    let num = neu::digit(10).repeat_times::<2>();
    let time = num.sep_once(":", num);
    let time = time.quote("[", "]").ws();
    let star = '*'.repeat_times::<3>().ws();
    let name = neu::whitespace().not().repeat_one_more().ws();
    let status = "left".or("joined").ws();
    let record = name.padded(star).then(status);
    let record = time.then(record).repeat(1..);
    let mut ctx = CharsCtx::new(
        r#"[20:59] *** jpn left
        [21:00] *** jpn joined
        [21:06] *** guifa left
        [21:07] *** guifa joined"#,
    );
    let records = ctx.ctor(&record)?;

    assert_eq!(records[0], (("20", "59"), ("jpn", "left")));
    assert_eq!(records[1], (("21", "00"), ("jpn", "joined")));
    assert_eq!(records[2], (("21", "06"), ("guifa", "left")));
    assert_eq!(records[3], (("21", "07"), ("guifa", "joined")));
    Ok(())
source§

fn ws( self ) -> Pad<C, T, NeureZeroMore<C, AsciiWhiteSpace, <C as Context<'a>>::Item, NullCond>>where C: Context<'a, Item = char>,

A shortcut for matching trailing ascii spaces.

Example
    let str = "file://      ";
    let val = "file://".ws();

    assert_eq!(CharsCtx::new(str).ctor(&val)?, "file://");
    assert_eq!(CharsCtx::new(str).try_mat(&val)?, Span::new(0, 13));

    Ok(())
source§

fn map<F, O>(self, func: F) -> Map<C, T, F, O>

source§

impl<'a, C, T> DynamicCreateCtorThenHelper<'a, C> for Twhere C: Context<'a> + Match<C>,

source§

fn dyn_then_ctor<F>(self, func: F) -> DynamicCreateCtorThen<C, T, F>

Construct a new regex with Ctor implementation based on previous result.

Example
    let num = u8::is_ascii_digit
        .repeat_one()
        .map(|v: &[u8]| String::from_utf8(v.to_vec()).map_err(|_| Error::Uid(0)))
        .map(map::from_str::<usize>());
    let num = num.clone().sep_once(b",", num);
    let re = num.dyn_then_ctor(|a: &(usize, usize)| {
        // leave the a's type empty cause rustc reject compile
        Ok(b'+'
            .repeat_range(a.0..a.0 + 1)
            .then(b'-'.repeat_range(a.1..a.1 + 1)))
    });

    assert_eq!(
        BytesCtx::new(b"3,0+++").ctor(&re)?,
        ((3, 0), ([43, 43, 43].as_slice(), [].as_slice()))
    );
    assert_eq!(
        BytesCtx::new(b"2,1++-").ctor(&re)?,
        ((2, 1), ([43, 43].as_slice(), [45].as_slice()))
    );
    assert_eq!(
        BytesCtx::new(b"0,3---").ctor(&re)?,
        ((0, 3), ([].as_slice(), [45, 45, 45].as_slice()))
    );
    Ok(())
source§

impl<'a, C, T> DynamicCreateRegexThenHelper<'a, C> for Twhere C: Context<'a> + Match<C>,

source§

fn dyn_then_re<F>(self, func: F) -> DynamicCreateRegexThen<C, T, F>

source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<'a, C, T> RegexIntoOp<'a, C> for Twhere T: Regex<C>, C: Context<'a>,

source§

fn into_box(self) -> BoxedRegex<C, T>

source§

fn into_rc(self) -> Rc<T, Global>

source§

fn into_arc(self) -> Arc<T, Global>

source§

fn into_cell(self) -> Cell<T>

source§

fn into_refcell(self) -> RefCell<T>

source§

fn into_mutex(self) -> Mutex<T>

source§

fn into_dyn_box<'b>( self ) -> Box<dyn Regex<C, Ret = <T as Regex<C>>::Ret> + 'b, Global>where T: Regex<C> + 'b,

source§

fn into_dyn_arc<'b>( self ) -> Arc<dyn Regex<C, Ret = <T as Regex<C>>::Ret> + 'b, Global>where T: Regex<C> + 'b,

source§

fn into_dyn_rc<'b>( self ) -> Rc<dyn Regex<C, Ret = <T as Regex<C>>::Ret> + 'b, Global>where T: Regex<C> + 'b,

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> MayDebug for T