Parse into ReplyCode

This commit is contained in:
Dirkjan Ochtman 2022-10-10 22:01:50 +02:00 committed by Damian Poddebniak
parent a3f2cdc5c0
commit 9fa64dee7a
1 changed files with 30 additions and 11 deletions

View File

@ -1,3 +1,5 @@
use std::str::FromStr;
use abnf_core::streaming::{is_ALPHA, is_DIGIT, CRLF, SP}; use abnf_core::streaming::{is_ALPHA, is_DIGIT, CRLF, SP};
use nom::{ use nom::{
branch::alt, branch::alt,
@ -10,7 +12,7 @@ use nom::{
use crate::{ use crate::{
parse::{address::address_literal, number, Domain}, parse::{address::address_literal, number, Domain},
types::{AuthMechanism, Capability, Response}, types::{AuthMechanism, Capability, ReplyCode, Response},
}; };
/// Greeting = ( "220 " (Domain / address-literal) [ SP textstring ] CRLF ) / /// Greeting = ( "220 " (Domain / address-literal) [ SP textstring ] CRLF ) /
@ -91,15 +93,32 @@ pub fn textstring(input: &[u8]) -> IResult<&[u8], &str> {
/// Reply-line = *( Reply-code "-" [ textstring ] CRLF ) /// Reply-line = *( Reply-code "-" [ textstring ] CRLF )
/// Reply-code [ SP textstring ] CRLF /// Reply-code [ SP textstring ] CRLF
pub fn Reply_line(input: &[u8]) -> IResult<&[u8], &[u8]> { pub fn Reply_lines(input: &[u8]) -> IResult<&[u8], Response> {
let parser = tuple(( let mut parser = map(
tuple((
many0(tuple((Reply_code, tag(b"-"), opt(textstring), CRLF))), many0(tuple((Reply_code, tag(b"-"), opt(textstring), CRLF))),
Reply_code, Reply_code,
opt(tuple((SP, textstring))), opt(tuple((SP, textstring))),
CRLF, CRLF,
)); )),
|(intermediate, code, text, _)| {
let mut lines =
Vec::with_capacity(intermediate.len() + if text.is_some() { 1 } else { 0 });
for (_, _, text, _) in intermediate {
if let Some(line) = text {
lines.push(line.to_owned());
}
}
let (remaining, parsed) = recognize(parser)(input)?; if let Some((_, line)) = text {
lines.push(line.to_owned());
}
Response::Other { code, lines }
},
);
let (remaining, parsed) = parser(input)?;
Ok((remaining, parsed)) Ok((remaining, parsed))
} }
@ -109,14 +128,14 @@ pub fn Reply_line(input: &[u8]) -> IResult<&[u8], &[u8]> {
/// 2345 /// 2345
/// 012345 /// 012345
/// 0123456789 /// 0123456789
pub fn Reply_code(input: &[u8]) -> IResult<&[u8], u16> { pub fn Reply_code(input: &[u8]) -> IResult<&[u8], ReplyCode> {
// FIXME: do not accept all codes. // FIXME: do not accept all codes.
map_res( map_res(
map_res( map_res(
take_while_m_n(3, 3, nom::character::is_digit), take_while_m_n(3, 3, nom::character::is_digit),
std::str::from_utf8, std::str::from_utf8,
), ),
str::parse, |s| u16::from_str(s).map(ReplyCode::from),
)(input) )(input)
} }