Make use of the custom sub-address separator
This commit is contained in:
parent
01220e6001
commit
071b3b5b76
4 changed files with 56 additions and 43 deletions
|
@ -11,16 +11,14 @@ pub struct CodedAddress {
|
|||
domain: Option<String>,
|
||||
}
|
||||
|
||||
impl FromStr for CodedAddress {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
impl CodedAddress {
|
||||
pub fn parse(s: &str, separator: char) -> Result<Self> {
|
||||
let (local_part, domain) = split_local_part(s);
|
||||
ensure!(!local_part.is_empty(), "{s}: local part cannot be empty");
|
||||
if let Some(dom) = &domain {
|
||||
ensure!(!dom.is_empty(), "{s}: domain cannot be empty");
|
||||
}
|
||||
let parts: Vec<&str> = local_part.split(crate::DEFAULT_SEPARATOR).collect();
|
||||
let parts: Vec<&str> = local_part.split(separator).collect();
|
||||
let local_part = parts[0].to_string();
|
||||
ensure!(!local_part.is_empty(), "{s}: local part cannot be empty");
|
||||
let sub_addr = if parts.len() >= 2 {
|
||||
|
@ -120,17 +118,17 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn parse_coded_addr_empty_email() {
|
||||
assert!(CodedAddress::from_str("").is_err());
|
||||
assert!(CodedAddress::parse("", '+').is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_coded_addr_empty_local() {
|
||||
assert!(CodedAddress::from_str("@example.com").is_err());
|
||||
assert!(CodedAddress::parse("@example.com", '+').is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_coded_addr_empty_domain() {
|
||||
assert!(CodedAddress::from_str("derp@").is_err());
|
||||
assert!(CodedAddress::parse("derp@", '+').is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -151,7 +149,7 @@ mod tests {
|
|||
#[test]
|
||||
fn parse_valid_coded_addr_with_domain() {
|
||||
let addr_str = "a+test+orsxg5a@example.org";
|
||||
let addr = CodedAddress::from_str(addr_str);
|
||||
let addr = CodedAddress::parse(addr_str, '+');
|
||||
assert!(addr.is_ok(), "unable to parse {addr_str}: {addr:?}");
|
||||
let addr = addr.unwrap();
|
||||
assert_eq!(addr.local_part, "a");
|
||||
|
@ -163,7 +161,7 @@ mod tests {
|
|||
#[test]
|
||||
fn parse_valid_coded_addr_without_domain() {
|
||||
let addr_str = "local.part+test+orsxg5a";
|
||||
let addr = CodedAddress::from_str(addr_str);
|
||||
let addr = CodedAddress::parse(addr_str, '+');
|
||||
assert!(addr.is_ok(), "unable to parse {addr_str}: {addr:?}");
|
||||
let addr = addr.unwrap();
|
||||
assert_eq!(addr.local_part, "local.part");
|
||||
|
@ -172,10 +170,22 @@ mod tests {
|
|||
assert!(addr.domain.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_valid_coded_addr_alt_sep() {
|
||||
let addr_str = "local-part.test.orsxg5a@example.org";
|
||||
let addr = CodedAddress::parse(addr_str, '.');
|
||||
assert!(addr.is_ok(), "unable to parse {addr_str}: {addr:?}");
|
||||
let addr = addr.unwrap();
|
||||
assert_eq!(addr.local_part, "local-part");
|
||||
assert_eq!(addr.sub_addr, Some("test".to_string()));
|
||||
assert_eq!(addr.code, b"test");
|
||||
assert_eq!(addr.domain, Some("example.org".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_valid_coded_addr_without_sub_addr() {
|
||||
let addr_str = "local.part@example.org";
|
||||
let addr = CodedAddress::from_str(addr_str);
|
||||
let addr = CodedAddress::parse(addr_str, '+');
|
||||
assert!(addr.is_ok(), "unable to parse {addr_str}: {addr:?}");
|
||||
let addr = addr.unwrap();
|
||||
assert_eq!(addr.local_part, "local.part");
|
||||
|
@ -232,29 +242,29 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn cmp_coded_addr_with_domain_eq() {
|
||||
let addr_1 = CodedAddress::from_str("test+test+orsxg5a@example.org").unwrap();
|
||||
let addr_2 = CodedAddress::from_str("test+test+orsxg5a@example.org").unwrap();
|
||||
let addr_1 = CodedAddress::parse("test+test+orsxg5a@example.org", '+').unwrap();
|
||||
let addr_2 = CodedAddress::parse("test+test+orsxg5a@example.org", '+').unwrap();
|
||||
assert_eq!(addr_1, addr_2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cmp_coded_addr_without_domain_eq() {
|
||||
let addr_1 = CodedAddress::from_str("test+test+orsxg5a").unwrap();
|
||||
let addr_2 = CodedAddress::from_str("test+test+orsxg5a").unwrap();
|
||||
let addr_1 = CodedAddress::parse("test+test+orsxg5a", '+').unwrap();
|
||||
let addr_2 = CodedAddress::parse("test+test+orsxg5a", '+').unwrap();
|
||||
assert_eq!(addr_1, addr_2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cmp_coded_addr_with_domain_ne() {
|
||||
let addr_1 = CodedAddress::from_str("test+test+orsxg5a@example.org").unwrap();
|
||||
let addr_2 = CodedAddress::from_str("test2+test+orsxg5a@example.org").unwrap();
|
||||
let addr_1 = CodedAddress::parse("test+test+orsxg5a@example.org", '+').unwrap();
|
||||
let addr_2 = CodedAddress::parse("test2+test+orsxg5a@example.org", '+').unwrap();
|
||||
assert_ne!(addr_1, addr_2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cmp_coded_addr_without_domain_ne() {
|
||||
let addr_1 = CodedAddress::from_str("test+test+orsxg5a").unwrap();
|
||||
let addr_2 = CodedAddress::from_str("test2+test+orsxg5a").unwrap();
|
||||
let addr_1 = CodedAddress::parse("test+test+orsxg5a", '+').unwrap();
|
||||
let addr_2 = CodedAddress::parse("test2+test+orsxg5a", '+').unwrap();
|
||||
assert_ne!(addr_1, addr_2);
|
||||
}
|
||||
|
||||
|
@ -289,35 +299,35 @@ mod tests {
|
|||
#[test]
|
||||
fn cmp_addr_types_with_domain_eq() {
|
||||
let addr_1 = KeyedAddress::from_str("test@example.org:3d74YQqk").unwrap();
|
||||
let addr_2 = CodedAddress::from_str("test+test+orsxg5a@example.org").unwrap();
|
||||
let addr_2 = CodedAddress::parse("test+test+orsxg5a@example.org", '+').unwrap();
|
||||
assert_eq!(addr_1, addr_2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cmp_addr_types_without_domain_eq() {
|
||||
let addr_1 = KeyedAddress::from_str("test:3d74YQqk").unwrap();
|
||||
let addr_2 = CodedAddress::from_str("test+test+orsxg5a").unwrap();
|
||||
let addr_2 = CodedAddress::parse("test+test+orsxg5a", '+').unwrap();
|
||||
assert_eq!(addr_1, addr_2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cmp_addr_types_without_sub_addr() {
|
||||
let addr_1 = KeyedAddress::from_str("test@example.org:3d74YQqk").unwrap();
|
||||
let addr_2 = CodedAddress::from_str("test@example.org").unwrap();
|
||||
let addr_2 = CodedAddress::parse("test@example.org", '+').unwrap();
|
||||
assert_eq!(addr_1, addr_2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cmp_addr_types_with_domain_ne() {
|
||||
let addr_1 = KeyedAddress::from_str("test@example.org:3d74YQqk").unwrap();
|
||||
let addr_2 = CodedAddress::from_str("test+test+orsxg5a@example.com").unwrap();
|
||||
let addr_2 = CodedAddress::parse("test+test+orsxg5a@example.com", '+').unwrap();
|
||||
assert_ne!(addr_1, addr_2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cmp_addr_types_without_domain_ne() {
|
||||
let addr_1 = KeyedAddress::from_str("test:3d74YQqk").unwrap();
|
||||
let addr_2 = CodedAddress::from_str("test2+test+orsxg5a").unwrap();
|
||||
let addr_2 = CodedAddress::parse("test2+test+orsxg5a", '+').unwrap();
|
||||
assert_ne!(addr_1, addr_2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,4 +37,8 @@ impl Config {
|
|||
}
|
||||
Ok(addr_set)
|
||||
}
|
||||
|
||||
pub fn get_separator(&self) -> char {
|
||||
self.separator
|
||||
}
|
||||
}
|
||||
|
|
33
src/input.rs
33
src/input.rs
|
@ -1,6 +1,5 @@
|
|||
use crate::address::CodedAddress;
|
||||
use anyhow::{anyhow, ensure, Result};
|
||||
use std::str::FromStr;
|
||||
|
||||
macro_rules! next_param {
|
||||
($it: ident) => {
|
||||
|
@ -25,7 +24,7 @@ impl Input {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn parse_input(input: &str) -> Result<Input> {
|
||||
pub fn parse_input(input: &str, separator: char) -> Result<Input> {
|
||||
let mut params_it = input.split(crate::PARAM_SEPARATOR);
|
||||
let stream = next_param!(params_it)?;
|
||||
ensure!(stream == "filter", "{stream}: invalid stream");
|
||||
|
@ -42,7 +41,7 @@ pub fn parse_input(input: &str) -> Result<Input> {
|
|||
let token = next_param!(params_it)?.to_string();
|
||||
ensure!(!token.is_empty(), "empty token");
|
||||
let address = next_param!(params_it)?.trim_end();
|
||||
let address = CodedAddress::from_str(address)?;
|
||||
let address = CodedAddress::parse(address, separator)?;
|
||||
Ok(Input {
|
||||
session_id,
|
||||
token,
|
||||
|
@ -57,7 +56,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_valid_input() {
|
||||
let input = "filter|0.5|1576146008.006099|smtp-in|rcpt-to|7641df9771b4ed00|1ef1c203cc576e5d|derp@example.com";
|
||||
let res = parse_input(input);
|
||||
let res = parse_input(input, '+');
|
||||
assert!(res.is_ok());
|
||||
let inp = res.unwrap();
|
||||
assert_eq!(inp.session_id, "7641df9771b4ed00");
|
||||
|
@ -66,83 +65,83 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_empty_input() {
|
||||
assert!(parse_input("").is_err());
|
||||
assert!(parse_input("", '+').is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_stream() {
|
||||
let input = "|0.5|1576146008.006099|smtp-in|rcpt-to|7641df9771b4ed00|1ef1c203cc576e5d|derp@example.com";
|
||||
assert!(parse_input(input).is_err());
|
||||
assert!(parse_input(input, '+').is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_stream() {
|
||||
let input = "invalid|0.5|1576146008.006099|smtp-in|rcpt-to|7641df9771b4ed00|1ef1c203cc576e5d|derp@example.com";
|
||||
assert!(parse_input(input).is_err());
|
||||
assert!(parse_input(input, '+').is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_version() {
|
||||
let input = "filter||1576146008.006099|smtp-in|rcpt-to|7641df9771b4ed00|1ef1c203cc576e5d|derp@example.com";
|
||||
assert!(parse_input(input).is_err());
|
||||
assert!(parse_input(input, '+').is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_timestamp() {
|
||||
let input =
|
||||
"filter|0.5||smtp-in|rcpt-to|7641df9771b4ed00|1ef1c203cc576e5d|derp@example.com";
|
||||
assert!(parse_input(input).is_err());
|
||||
assert!(parse_input(input, '+').is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_subsystem() {
|
||||
let input = "filter|0.5|1576146008.006099||rcpt-to|7641df9771b4ed00|1ef1c203cc576e5d|derp@example.com";
|
||||
assert!(parse_input(input).is_err());
|
||||
assert!(parse_input(input, '+').is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_subsystem() {
|
||||
let input = "filter|0.5|1576146008.006099|invalid|rcpt-to|7641df9771b4ed00|1ef1c203cc576e5d|derp@example.com";
|
||||
assert!(parse_input(input).is_err());
|
||||
assert!(parse_input(input, '+').is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_phase() {
|
||||
let input = "filter|0.5|1576146008.006099|smtp-in||7641df9771b4ed00|1ef1c203cc576e5d|derp@example.com";
|
||||
assert!(parse_input(input).is_err());
|
||||
assert!(parse_input(input, '+').is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_phase() {
|
||||
let input = "filter|0.5|1576146008.006099|smtp-in|invalid|7641df9771b4ed00|1ef1c203cc576e5d|derp@example.com";
|
||||
assert!(parse_input(input).is_err());
|
||||
assert!(parse_input(input, '+').is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_id() {
|
||||
let input =
|
||||
"filter|0.5|1576146008.006099|smtp-in|rcpt-to||1ef1c203cc576e5d|derp@example.com";
|
||||
assert!(parse_input(input).is_err());
|
||||
assert!(parse_input(input, '+').is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_token() {
|
||||
let input =
|
||||
"filter|0.5|1576146008.006099|smtp-in|rcpt-to|7641df9771b4ed00||derp@example.com";
|
||||
assert!(parse_input(input).is_err());
|
||||
assert!(parse_input(input, '+').is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_data() {
|
||||
let input =
|
||||
"filter|0.5|1576146008.006099|smtp-in|rcpt-to|7641df9771b4ed00|1ef1c203cc576e5d|";
|
||||
assert!(parse_input(input).is_err());
|
||||
assert!(parse_input(input, '+').is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_missing_data() {
|
||||
let input =
|
||||
"filter|0.5|1576146008.006099|smtp-in|rcpt-to|7641df9771b4ed00|1ef1c203cc576e5d";
|
||||
assert!(parse_input(input).is_err());
|
||||
assert!(parse_input(input, '+').is_err());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ pub fn start_service() -> Result<()> {
|
|||
if buffer.is_empty() {
|
||||
continue;
|
||||
}
|
||||
match parse_input(&buffer) {
|
||||
match parse_input(&buffer, cfg.get_separator()) {
|
||||
Ok(input) => {
|
||||
if allow_email(&input, &addresses) {
|
||||
input.answer(ANSWER_OK);
|
||||
|
@ -71,7 +71,7 @@ mod tests {
|
|||
fn run_test_with_addr(address: &str) -> bool {
|
||||
// Preparing the input
|
||||
let input_str = format!("filter|0.5|1576146008.006099|smtp-in|rcpt-to|7641df9771b4ed00|1ef1c203cc576e5d|{address}");
|
||||
let input = parse_input(&input_str);
|
||||
let input = parse_input(&input_str, '+');
|
||||
assert!(input.is_ok());
|
||||
let input = input.unwrap();
|
||||
|
||||
|
|
Loading…
Reference in a new issue