85 lines
2.6 KiB
Rust
85 lines
2.6 KiB
Rust
use nom::{
|
|
branch::alt,
|
|
bytes::complete::is_not,
|
|
bytes::complete::tag,
|
|
character::{
|
|
self,
|
|
complete::{alpha1, multispace1},
|
|
},
|
|
multi::many_m_n,
|
|
sequence::preceded,
|
|
IResult,
|
|
};
|
|
use tracing::trace;
|
|
|
|
use crate::{parser::utils::key_value, Methods, ServerSettings};
|
|
|
|
fn parse_version(input: &str) -> IResult<&str, Vec<i32>> {
|
|
many_m_n(
|
|
1,
|
|
5,
|
|
alt((
|
|
character::complete::i32,
|
|
preceded(character::complete::char('.'), character::complete::i32),
|
|
)),
|
|
)(input)
|
|
}
|
|
|
|
fn parse_methods(input: &str) -> IResult<&str, Vec<Methods>> {
|
|
let (rem, res) = many_m_n(1, 10, alt((alpha1, preceded(multispace1, alpha1))))(input)?;
|
|
let methods = res
|
|
.into_iter()
|
|
.map(|m| match m {
|
|
"PLAIN" => Methods::Plain,
|
|
"OAUTHBEARER" => Methods::OAuthbearer,
|
|
any => todo!("That method is not yet implemented: {}", any),
|
|
})
|
|
.collect();
|
|
Ok((rem, methods))
|
|
}
|
|
|
|
fn parse_extensions(input: &str) -> IResult<&str, Vec<String>> {
|
|
let space_then_word = preceded(tag(" "), is_not(" "));
|
|
let word = is_not(" ");
|
|
let (rem, res) = many_m_n(1, 200, alt((word, space_then_word)))(input)?;
|
|
let extensions = res.into_iter().map(|m| m.to_string()).collect();
|
|
Ok((rem, extensions))
|
|
}
|
|
|
|
pub fn parse_server_config(input: &str) -> IResult<&str, ServerSettings> {
|
|
let (remain, (_key, implementation)) = key_value(input)?;
|
|
trace!("Implementation:# {}", implementation);
|
|
let (remain, (_key, version)) = key_value(remain)?;
|
|
trace!("{}", version);
|
|
let (_, version) = parse_version(version)?;
|
|
trace!("Version:# {:?}", version);
|
|
let (remain, (_key, sasl)) = key_value(remain)?;
|
|
trace!("{}", sasl);
|
|
let (_, sasl) = parse_methods(sasl)?;
|
|
trace!("SASL:# {:?}", sasl);
|
|
let (remain, (_key, capabilities)) = key_value(remain)?;
|
|
trace!("{}", capabilities);
|
|
let (_, capabilities) = parse_extensions(capabilities)?;
|
|
trace!("Extensions:# {:?}", &capabilities);
|
|
let (remain, (_key, notify)) = key_value(remain)?;
|
|
trace!("{}", notify);
|
|
let (_, notify) = parse_extensions(remain)?;
|
|
trace!("Notify:# {:?}", ¬ify);
|
|
let (remain, (_key, max_redirects)) = key_value(remain)?;
|
|
trace!("{}", max_redirects);
|
|
let (_, max_redirects) = character::complete::u32(max_redirects)?;
|
|
trace!("Max Redirects:# {}", max_redirects);
|
|
|
|
IResult::Ok((
|
|
remain,
|
|
ServerSettings {
|
|
implementation: implementation.to_string(),
|
|
version,
|
|
sasl,
|
|
capabilities,
|
|
notify,
|
|
max_redirects,
|
|
},
|
|
))
|
|
}
|