oni_comb_parser/text/
identifier.rs1use crate::error::ParseError;
2use crate::fail::{Fail, PResult};
3use crate::input::Input;
4use crate::parser::Parser;
5use crate::str_input::StrInput;
6
7pub struct Identifier;
8
9pub fn identifier() -> Identifier {
10 Identifier
11}
12
13impl<'a> Parser<StrInput<'a>> for Identifier {
14 type Error = ParseError;
15 type Output = &'a str;
16
17 #[inline]
18 fn parse_next(&mut self, input: &mut StrInput<'a>) -> PResult<&'a str, ParseError> {
19 let pos = input.offset();
20 let remaining = input.as_str();
21 let mut chars = remaining.chars();
22
23 match chars.next() {
24 Some(c) if c.is_ascii_alphabetic() || c == '_' => {}
25 _ => {
26 return Err(Fail::Backtrack(ParseError::expected_description(pos, "identifier")));
27 }
28 }
29
30 let mut consumed = remaining.chars().next().unwrap().len_utf8();
31 for c in chars {
32 if c.is_ascii_alphanumeric() || c == '_' {
33 consumed += c.len_utf8();
34 } else {
35 break;
36 }
37 }
38
39 input.advance(consumed);
40 Ok(&remaining[..consumed])
41 }
42}