versions/
parsers.rs

1//! Reusable parsers for the `versions` library.
2
3use nom::branch::alt;
4use nom::bytes::complete::{tag, take_while1};
5use nom::character::complete::{char, digit1};
6use nom::combinator::{map, map_res};
7use nom::{IResult, Parser};
8
9/// Parse an unsigned integer.
10///
11/// Should yield either a zero on its own, or some other multi-digit number.
12pub(crate) fn unsigned(i: &str) -> IResult<&str, u32> {
13    map_res(alt((tag("0"), digit1)), |s: &str| s.parse::<u32>()).parse(i)
14}
15
16#[test]
17fn unsigned_test() {
18    assert!(unsigned("0").is_ok());
19    assert!(unsigned("123").is_ok());
20
21    match unsigned("06") {
22        Ok(("6", 0)) => {}
23        Ok(_) => panic!("Parsed 06, but gave wrong output"),
24        Err(_) => panic!("Couldn't parse 06"),
25    }
26}
27
28/// Some alphanumeric combination, possibly punctuated by `-` characters.
29pub(crate) fn hyphenated_alphanums(i: &str) -> IResult<&str, &str> {
30    take_while1(|c: char| c.is_ascii_alphanumeric() || c == '-')(i)
31}
32
33/// Some alphanumeric combination.
34pub(crate) fn alphanums(i: &str) -> IResult<&str, &str> {
35    take_while1(|c: char| c.is_ascii_alphanumeric())(i)
36}
37
38/// Parse metadata. As of SemVer 2.0, this can contain alphanumeric characters
39/// as well as hyphens.
40pub fn meta(i: &str) -> IResult<&str, String> {
41    let (i, _) = char('+')(i)?;
42    map(
43        take_while1(|c: char| c.is_ascii_alphanumeric() || c == '-' || c == '.'),
44        |s: &str| s.to_owned(),
45    )
46    .parse(i)
47}