sieverman/src/parser/server_config.rs

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:# {:?}", &notify);
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,
},
))
}