mirror of
https://github.com/KumoCorp/kumomta.git
synced 2026-10-27 16:00:37 +00:00
No functional changes, just adds some illustrative unit tests that show that the routing domain portion of the queue name string can accept a port number. The system doesn't understand what to do about that at this time. refs: https://github.com/KumoCorp/kumomta/issues/352
245 lines
5.7 KiB
Rust
245 lines
5.7 KiB
Rust
#[derive(Debug)]
|
|
pub struct QueueNameComponents<'a> {
|
|
pub campaign: Option<&'a str>,
|
|
pub tenant: Option<&'a str>,
|
|
pub domain: &'a str,
|
|
pub routing_domain: Option<&'a str>,
|
|
}
|
|
|
|
fn crack_domain(domain: &str) -> (&str, Option<&str>) {
|
|
match domain.split_once('!') {
|
|
Some((domain, routing_domain)) => (domain, Some(routing_domain)),
|
|
None => (domain, None),
|
|
}
|
|
}
|
|
|
|
impl<'a> QueueNameComponents<'a> {
|
|
pub fn parse(name: &'a str) -> Self {
|
|
match name.split_once('@') {
|
|
Some((prefix, domain)) => match prefix.split_once(':') {
|
|
Some((campaign, tenant)) => {
|
|
let (domain, routing_domain) = crack_domain(domain);
|
|
Self {
|
|
campaign: Some(campaign),
|
|
tenant: Some(tenant),
|
|
domain,
|
|
routing_domain,
|
|
}
|
|
}
|
|
None => {
|
|
let (domain, routing_domain) = crack_domain(domain);
|
|
Self {
|
|
campaign: None,
|
|
tenant: Some(prefix),
|
|
domain,
|
|
routing_domain,
|
|
}
|
|
}
|
|
},
|
|
None => {
|
|
let (domain, routing_domain) = crack_domain(name);
|
|
Self {
|
|
campaign: None,
|
|
tenant: None,
|
|
domain,
|
|
routing_domain,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn to_string(&self) -> String {
|
|
Self::format(self.campaign, self.tenant, self.domain, self.routing_domain)
|
|
}
|
|
|
|
pub fn format<C: AsRef<str>, T: AsRef<str>, D: AsRef<str>, RD: AsRef<str>>(
|
|
campaign: Option<C>,
|
|
tenant: Option<T>,
|
|
domain: D,
|
|
routing_domain: Option<RD>,
|
|
) -> String {
|
|
let campaign: Option<&str> = campaign.as_ref().map(|c| c.as_ref());
|
|
let tenant: Option<&str> = tenant.as_ref().map(|c| c.as_ref());
|
|
let routing_domain: Option<String> =
|
|
routing_domain.as_ref().map(|c| format!("!{}", c.as_ref()));
|
|
let routing_domain = routing_domain.as_deref().unwrap_or("");
|
|
let domain: &str = domain.as_ref();
|
|
match (campaign, tenant) {
|
|
(Some(c), Some(t)) => format!("{c}:{t}@{domain}{routing_domain}"),
|
|
(Some(c), None) => format!("{c}:@{domain}{routing_domain}"),
|
|
(None, Some(t)) => format!("{t}@{domain}{routing_domain}"),
|
|
(None, None) => format!("{domain}{routing_domain}"),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_routing_domain_syntax() {
|
|
k9::assert_equal!(crack_domain("foo.com"), ("foo.com", None));
|
|
k9::assert_equal!(
|
|
crack_domain("foo.com!bar.com"),
|
|
("foo.com", Some("bar.com"))
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_routing_domain_with_port() {
|
|
k9::snapshot!(
|
|
QueueNameComponents::parse("foo.com:2025"),
|
|
r#"
|
|
QueueNameComponents {
|
|
campaign: None,
|
|
tenant: None,
|
|
domain: "foo.com:2025",
|
|
routing_domain: None,
|
|
}
|
|
"#
|
|
);
|
|
|
|
k9::snapshot!(
|
|
QueueNameComponents::parse("foo.com!routing.com:2025"),
|
|
r#"
|
|
QueueNameComponents {
|
|
campaign: None,
|
|
tenant: None,
|
|
domain: "foo.com",
|
|
routing_domain: Some(
|
|
"routing.com:2025",
|
|
),
|
|
}
|
|
"#
|
|
);
|
|
|
|
k9::snapshot!(
|
|
QueueNameComponents::parse("tenant@foo.com!routing.com:2025"),
|
|
r#"
|
|
QueueNameComponents {
|
|
campaign: None,
|
|
tenant: Some(
|
|
"tenant",
|
|
),
|
|
domain: "foo.com",
|
|
routing_domain: Some(
|
|
"routing.com:2025",
|
|
),
|
|
}
|
|
"#
|
|
);
|
|
|
|
k9::snapshot!(
|
|
QueueNameComponents::parse("campaign:@foo.com!routing.com:2025"),
|
|
r#"
|
|
QueueNameComponents {
|
|
campaign: Some(
|
|
"campaign",
|
|
),
|
|
tenant: Some(
|
|
"",
|
|
),
|
|
domain: "foo.com",
|
|
routing_domain: Some(
|
|
"routing.com:2025",
|
|
),
|
|
}
|
|
"#
|
|
);
|
|
|
|
k9::snapshot!(
|
|
QueueNameComponents::parse("campaign:tenant@foo.com!routing.com:2025"),
|
|
r#"
|
|
QueueNameComponents {
|
|
campaign: Some(
|
|
"campaign",
|
|
),
|
|
tenant: Some(
|
|
"tenant",
|
|
),
|
|
domain: "foo.com",
|
|
routing_domain: Some(
|
|
"routing.com:2025",
|
|
),
|
|
}
|
|
"#
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_queue_name() {
|
|
k9::snapshot!(
|
|
QueueNameComponents::parse("foo.com"),
|
|
r#"
|
|
QueueNameComponents {
|
|
campaign: None,
|
|
tenant: None,
|
|
domain: "foo.com",
|
|
routing_domain: None,
|
|
}
|
|
"#
|
|
);
|
|
k9::snapshot!(
|
|
QueueNameComponents::parse("tenant@foo.com"),
|
|
r#"
|
|
QueueNameComponents {
|
|
campaign: None,
|
|
tenant: Some(
|
|
"tenant",
|
|
),
|
|
domain: "foo.com",
|
|
routing_domain: None,
|
|
}
|
|
"#
|
|
);
|
|
k9::snapshot!(
|
|
QueueNameComponents::parse("campaign:@foo.com"),
|
|
r#"
|
|
QueueNameComponents {
|
|
campaign: Some(
|
|
"campaign",
|
|
),
|
|
tenant: Some(
|
|
"",
|
|
),
|
|
domain: "foo.com",
|
|
routing_domain: None,
|
|
}
|
|
"#
|
|
);
|
|
k9::snapshot!(
|
|
QueueNameComponents::parse("campaign:tenant@foo.com"),
|
|
r#"
|
|
QueueNameComponents {
|
|
campaign: Some(
|
|
"campaign",
|
|
),
|
|
tenant: Some(
|
|
"tenant",
|
|
),
|
|
domain: "foo.com",
|
|
routing_domain: None,
|
|
}
|
|
"#
|
|
);
|
|
k9::snapshot!(
|
|
QueueNameComponents::parse("campaign:tenant@foo.com!routing.com"),
|
|
r#"
|
|
QueueNameComponents {
|
|
campaign: Some(
|
|
"campaign",
|
|
),
|
|
tenant: Some(
|
|
"tenant",
|
|
),
|
|
domain: "foo.com",
|
|
routing_domain: Some(
|
|
"routing.com",
|
|
),
|
|
}
|
|
"#
|
|
);
|
|
}
|
|
}
|