diff options
author | Urgau | 2023-02-07 19:15:39 +0000 |
---|---|---|
committer | Blaž Hrastnik | 2023-03-08 01:48:35 +0000 |
commit | e973b71c83dcefbdb3a748f28ce3bfd51e9cd842 (patch) | |
tree | 9071c629cb395524ec97265ca898f37615468907 /helix-parsec | |
parent | 9c12e0fb765f065b43788da670ffb98159d64a5f (diff) |
Optimize LSP snippet parsing
Diffstat (limited to 'helix-parsec')
-rw-r--r-- | helix-parsec/src/lib.rs | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/helix-parsec/src/lib.rs b/helix-parsec/src/lib.rs index c86a1a05..bfa981e5 100644 --- a/helix-parsec/src/lib.rs +++ b/helix-parsec/src/lib.rs @@ -157,6 +157,35 @@ where } } +/// A parser which matches all values until the specified pattern no longer match. +/// +/// This parser only ever fails if the input has a length of zero. +/// +/// # Examples +/// +/// ``` +/// use helix_parsec::{take_while, Parser}; +/// let parser = take_while(|c| c == '1'); +/// assert_eq!(Ok(("2", "11")), parser.parse("112")); +/// assert_eq!(Err("22"), parser.parse("22")); +/// ``` +pub fn take_while<'a, F>(pattern: F) -> impl Parser<'a, Output = &'a str> +where + F: Fn(char) -> bool, +{ + move |input: &'a str| match input + .char_indices() + .take_while(|(_p, c)| pattern(*c)) + .last() + { + Some((index, c)) => { + let index = index + c.len_utf8(); + Ok((&input[index..], &input[0..index])) + } + _ => Err(input), + } +} + // Variadic parser combinators /// A parser combinator which matches a sequence of parsers in an all-or-nothing fashion. |