use crate::parsers::{ws, ParseResult, Span};
use crate::types::Name;
use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::character::complete::{alpha1, digit1};
use nom::combinator::{map, recognize};
use nom::multi::many0;
use nom::sequence::tuple;
pub fn parse_name<'a, T: Into<Span<'a>>>(input: T) -> ParseResult<'a, Name> {
map(
ws(recognize(tuple((alpha1, many0(parse_any_char))))),
|x: Span| Name::from(*x.fragment()),
)(input.into())
}
pub fn parse_any_char(input: Span) -> ParseResult<Span> {
recognize(alt((alpha1, digit1, tag("-"), tag("_"))))(input)
}
impl crate::parsers::Parser for Name {
type Item = Name;
fn parse<'a, S: Into<Span<'a>>>(input: S) -> ParseResult<'a, Self::Item> {
parse_name(input)
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::parsers::Match;
use crate::Parser;
#[test]
fn parse_name_works() {
assert!(Name::parse(Span::new("abcde")).is_exactly("abcde"));
}
#[test]
fn parse_any_char_works() {
assert!(parse_any_char(Span::new("abc")).is_exactly("abc"));
assert!(parse_any_char(Span::new("1")).is_exactly("1"));
assert!(parse_any_char(Span::new("-.")).is_result(".", "-"));
assert!(parse_any_char(Span::new("_")).is_exactly("_"));
assert!(parse_any_char(Span::new(".")).is_err());
assert!(parse_any_char(Span::new(".")).is_err());
}
}