This repository has been archived on 2023-09-20. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
rust-opensmtpd/src/parsers/mod.rs
Rodolphe Bréard a6d4dd21c1 Rewrite the project
The previous project architecture was far too complicated and hard to
maintain. The new one is much more simple. Although procedural macros
are cools, they are a no-go on Rust-OpenSMTPD.

Reports and filter are implemented (except data-line) but untested.
2020-11-25 18:04:16 +01:00

66 lines
1.5 KiB
Rust

pub(crate) mod entry;
pub(crate) mod handshake;
pub(crate) mod parameters;
use nom::branch::alt;
use nom::bytes::streaming::{tag, take_while1};
use nom::combinator::map_res;
use nom::IResult;
use std::str::FromStr;
fn is_body_char(c: u8) -> bool {
!(c as char).is_control()
}
fn is_parameter_char(c: u8) -> bool {
is_body_char(c) && (c as char) != '|'
}
fn parse_string_parameter(input: &[u8]) -> IResult<&[u8], String> {
let (input, s) = take_while1(is_parameter_char)(input)?;
Ok((input, String::from_utf8(s.to_vec()).unwrap()))
}
fn parse_data_structure<T>(input: &[u8]) -> IResult<&[u8], T>
where
T: FromStr,
{
map_res(take_while1(is_parameter_char), |s: &[u8]| {
T::from_str(&String::from_utf8_lossy(s))
})(input)
}
fn parse_delimiter(input: &[u8]) -> IResult<&[u8], &[u8]> {
tag("|")(input)
}
fn parse_eol(input: &[u8]) -> IResult<&[u8], &[u8]> {
alt((tag("\r\n"), tag("\n")))(input)
}
fn parse_usize(input: &[u8]) -> IResult<&[u8], usize> {
map_res(take_while1(|c| (c as char).is_ascii_digit()), |s| {
usize::from_str_radix(&String::from_utf8_lossy(s), 10)
})(input)
}
#[cfg(test)]
mod tests {
use super::is_parameter_char;
#[test]
fn test_valid_parameter_char() {
let char_lst = "a0.:-_/";
for c in char_lst.bytes() {
assert!(is_parameter_char(c));
}
}
#[test]
fn test_invalid_parameter_char() {
let char_lst = "|\n";
for c in char_lst.bytes() {
assert!(!is_parameter_char(c));
}
}
}