use crate::parse::command::Ldh_str;
use abnf_core::streaming::is_DIGIT;
use nom::{
branch::alt,
bytes::streaming::{tag, tag_no_case, take_while1, take_while_m_n},
character::is_hex_digit,
combinator::{opt, recognize},
multi::{count, many_m_n},
sequence::tuple,
IResult,
};
pub fn IPv4_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((Snum, count(tuple((tag(b"."), Snum)), 3)));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn IPv6_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((tag_no_case(b"IPv6:"), IPv6_addr));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn General_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((Standardized_tag, tag(b":"), take_while1(is_dcontent)));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn Standardized_tag(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = Ldh_str;
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn is_dcontent(byte: u8) -> bool {
matches!(byte, 33..=90 | 94..=126)
}
pub fn Snum(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = take_while_m_n(1, 3, is_DIGIT);
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn IPv6_addr(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = alt((IPv6_full, IPv6_comp, IPv6v4_full, IPv6v4_comp));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn IPv6_hex(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = take_while_m_n(1, 4, is_hex_digit);
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn IPv6_full(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((IPv6_hex, count(tuple((tag(b":"), IPv6_hex)), 7)));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn IPv6_comp(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((
opt(tuple((
IPv6_hex,
many_m_n(0, 5, tuple((tag(b":"), IPv6_hex))),
))),
tag(b"::"),
opt(tuple((
IPv6_hex,
many_m_n(0, 5, tuple((tag(b":"), IPv6_hex))),
))),
));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn IPv6v4_full(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((
IPv6_hex,
count(tuple((tag(b":"), IPv6_hex)), 5),
tag(b":"),
IPv4_address_literal,
));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}
pub fn IPv6v4_comp(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((
opt(tuple((
IPv6_hex,
many_m_n(0, 3, tuple((tag(b":"), IPv6_hex))),
))),
tag(b"::"),
opt(tuple((
IPv6_hex,
many_m_n(0, 3, tuple((tag(b":"), IPv6_hex))),
tag(b":"),
))),
IPv4_address_literal,
));
let (remaining, parsed) = recognize(parser)(input)?;
Ok((remaining, parsed))
}