In RFC1738, the BNF for domainlabel
is the following:
domainlabel = alphadigit | alphadigit *[ alphadigit | "-" ] alphadigit
That is, it's either an alphadigit, or it's a string where the first/last characters have to be an alphadigit but the intermediate characters can be an alphadigit or a dash.
How do I implement this with nom? Ignoring the single character scenario to simplify the case, my final attempt is:
fn domain_label(s: &[u8]) -> IResult<&[u8], (&[u8], &[u8], &[u8])> {
let left = take_while_m_n(1, 1, is_alphanumeric);
let middle = take_while(|c| is_alphanumeric(c) || c == b'-');
let right = take_while_m_n(1, 1, is_alphanumeric);
let whole = tuple((left, middle, right));
whole(s)
}
The problem with this is that middle
can consume the last character and hence right
fails because there is no character to consume.
println!("{:?}", domain_label(b"abcde"));
Err(Error(([], TakeWhileMN)))
Parsers should be able to attempt all possible consumption paths, but how to do this with nom
?