use crate::{
Character,
TextInput
};
use pups_core::{
Input,
Mode,
ParseResult::{
self,
Failure,
Success,
},
Parser
};
pub struct UnicodeIdentifier;
impl<C, I> Parser<I> for UnicodeIdentifier
where
C: Character,
I: Input<Item = C> + TextInput,
{
type Output = String;
type Error = ();
type Message = ();
fn apply<_Mode: Mode>(
&self,
input: &mut I
) -> ParseResult<String, (), (), _Mode> {
let cursor: usize = input.cursor();
if let Some (character) = input.next() && character.is_unicode_identifier_start() {
let mut identifier: _Mode::OutputForm<String> = _Mode::convert_output({
let mut identifier: String = String::new();
character.write(&mut identifier);
identifier
});
loop {
let cursor: usize = input.cursor();
let Some (character) = input.next() else { break; };
if !character.is_unicode_identifier_continuation() {
input.set_cursor(cursor);
break;
};
identifier = _Mode::merge_outputs(
identifier,
_Mode::convert_output(character),
|mut i, c: C| { c.write(&mut i); i }
);
}
Success (identifier, _Mode::new_message_container())
} else {
input.set_cursor(cursor);
Failure (_Mode::convert_error(()), _Mode::new_message_container())
}
}
}