Config expressions passing tests.

This commit is contained in:
mdecimus
2024-01-19 13:06:39 +01:00
parent 4551576e04
commit 02faa04e27
44 changed files with 344 additions and 304 deletions

View File

@@ -27,9 +27,12 @@ use deadpool::{
};
use std::{sync::Arc, time::Duration};
use store::{Store, Stores};
use utils::config::{
utils::{AsKey, ParseValue},
Config, Servers,
use utils::{
config::{
utils::{AsKey, ParseValue},
Config, Servers,
},
expr::Token,
};
use ahash::AHashMap;
@@ -171,9 +174,13 @@ impl AddressMapping {
"Invalid value for address mapping {key:?}: {value:?}",
)),
}
} else if let Some(if_block) =
config.parse_if_block(key, |name| Err(format!("Invalid variable name {name:?}.",)))?
{
} else if let Some(if_block) = config.parse_if_block(key, |name| {
if ["address", "email"].contains(&name) {
Ok(Token::Variable(1))
} else {
Err(format!("Invalid variable name {name:?}.",))
}
})? {
Ok(AddressMapping::Custom(if_block))
} else {
Ok(AddressMapping::Disable)

View File

@@ -300,15 +300,21 @@ impl AddressMapping {
}
}
AddressMapping::Custom(if_block) => {
let result = if_block
.eval(
|_| Variable::default(),
|_, _| async { Variable::default() },
)
.await
.into_string();
if !result.is_empty() {
return result.into_owned().into();
if let Ok(result) = String::try_from(
if_block
.eval(
|name| {
if name == 1 {
Variable::from(address)
} else {
Variable::default()
}
},
|_, _| async { Variable::default() },
)
.await,
) {
return result.into();
}
}
AddressMapping::Disable => (),
@@ -323,16 +329,23 @@ impl AddressMapping {
.rsplit_once('@')
.map(|(_, domain_part)| format!("@{}", domain_part))
.map(Cow::Owned),
AddressMapping::Custom(if_block) => {
let result = if_block
.eval(
|_| Variable::default(),
|_, _| async { Variable::default() },
)
.await
.into_string();
if !result.is_empty() {
Some(result.into_owned().into())
if let Ok(result) = String::try_from(
if_block
.eval(
|name| {
if name == 1 {
Variable::from(address)
} else {
Variable::default()
}
},
|_, _| async { Variable::default() },
)
.await,
) {
Some(result.into())
} else {
None
}

View File

@@ -305,9 +305,9 @@ impl<'x> TryFrom<expr::Variable<'x>> for VerifyStrategy {
fn try_from(value: expr::Variable<'x>) -> Result<Self, Self::Error> {
match value {
expr::Variable::Integer(c) => match c {
0 => Ok(VerifyStrategy::Relaxed),
1 => Ok(VerifyStrategy::Strict),
2 => Ok(VerifyStrategy::Disable),
2 => Ok(VerifyStrategy::Relaxed),
3 => Ok(VerifyStrategy::Strict),
4 => Ok(VerifyStrategy::Disable),
_ => Err(()),
},
_ => Err(()),
@@ -318,9 +318,9 @@ impl<'x> TryFrom<expr::Variable<'x>> for VerifyStrategy {
impl From<VerifyStrategy> for Constant {
fn from(value: VerifyStrategy) -> Self {
Constant::Integer(match value {
VerifyStrategy::Relaxed => 0,
VerifyStrategy::Strict => 1,
VerifyStrategy::Disable => 2,
VerifyStrategy::Relaxed => 2,
VerifyStrategy::Strict => 3,
VerifyStrategy::Disable => 4,
})
}
}

View File

@@ -382,9 +382,9 @@ impl<'x> TryFrom<Variable<'x>> for RequireOptional {
fn try_from(value: Variable<'x>) -> Result<Self, Self::Error> {
match value {
utils::expr::Variable::Integer(0) => Ok(RequireOptional::Optional),
utils::expr::Variable::Integer(2) => Ok(RequireOptional::Optional),
utils::expr::Variable::Integer(1) => Ok(RequireOptional::Require),
utils::expr::Variable::Integer(2) => Ok(RequireOptional::Disable),
utils::expr::Variable::Integer(0) => Ok(RequireOptional::Disable),
_ => Err(()),
}
}
@@ -393,9 +393,9 @@ impl<'x> TryFrom<Variable<'x>> for RequireOptional {
impl From<RequireOptional> for Constant {
fn from(value: RequireOptional) -> Self {
Constant::Integer(match value {
RequireOptional::Optional => 0,
RequireOptional::Optional => 2,
RequireOptional::Require => 1,
RequireOptional::Disable => 2,
RequireOptional::Disable => 0,
})
}
}

View File

@@ -214,9 +214,9 @@ impl From<AggregateFrequency> for Constant {
fn from(value: AggregateFrequency) -> Self {
match value {
AggregateFrequency::Never => 0.into(),
AggregateFrequency::Hourly => 1.into(),
AggregateFrequency::Daily => 2.into(),
AggregateFrequency::Weekly => 3.into(),
AggregateFrequency::Hourly => 2.into(),
AggregateFrequency::Daily => 3.into(),
AggregateFrequency::Weekly => 4.into(),
}
}
}
@@ -227,9 +227,9 @@ impl<'x> TryFrom<Variable<'x>> for AggregateFrequency {
fn try_from(value: Variable<'x>) -> Result<Self, Self::Error> {
match value {
Variable::Integer(0) => Ok(AggregateFrequency::Never),
Variable::Integer(1) => Ok(AggregateFrequency::Hourly),
Variable::Integer(2) => Ok(AggregateFrequency::Daily),
Variable::Integer(3) => Ok(AggregateFrequency::Weekly),
Variable::Integer(2) => Ok(AggregateFrequency::Hourly),
Variable::Integer(3) => Ok(AggregateFrequency::Daily),
Variable::Integer(4) => Ok(AggregateFrequency::Weekly),
_ => Err(()),
}
}

View File

@@ -31,7 +31,6 @@ use super::{ConfigContext, RelayHost};
pub trait ConfigShared {
fn parse_shared(&self, ctx: &ConfigContext) -> super::Result<Shared>;
fn parse_host(&self, id: &str) -> super::Result<RelayHost>;
}

View File

@@ -122,15 +122,15 @@ impl ParseTrottleKey for &str {
fn parse_throttle_key(&self, key: &str) -> super::Result<u16> {
match *self {
"rcpt" => Ok(THROTTLE_RCPT),
"rcpt-domain" => Ok(THROTTLE_RCPT_DOMAIN),
"rcpt_domain" => Ok(THROTTLE_RCPT_DOMAIN),
"sender" => Ok(THROTTLE_SENDER),
"sender-domain" => Ok(THROTTLE_SENDER_DOMAIN),
"authenticated-as" => Ok(THROTTLE_AUTH_AS),
"sender_domain" => Ok(THROTTLE_SENDER_DOMAIN),
"authenticated_as" => Ok(THROTTLE_AUTH_AS),
"listener" => Ok(THROTTLE_LISTENER),
"mx" => Ok(THROTTLE_MX),
"remote-ip" => Ok(THROTTLE_REMOTE_IP),
"local-ip" => Ok(THROTTLE_LOCAL_IP),
"helo-domain" => Ok(THROTTLE_HELO_DOMAIN),
"remote_ip" => Ok(THROTTLE_REMOTE_IP),
"local_ip" => Ok(THROTTLE_LOCAL_IP),
"helo_domain" => Ok(THROTTLE_HELO_DOMAIN),
_ => Err(format!("Invalid throttle key {self:?} found in {key:?}")),
}
}

View File

@@ -33,20 +33,14 @@ pub const F_KEY_EXISTS: u32 = 2;
pub const VARIABLES_MAP: &[(&str, u32)] = &[
("rcpt", V_RECIPIENT),
("rcpt-domain", V_RECIPIENT_DOMAIN),
("rcpt_domain", V_RECIPIENT_DOMAIN),
("sender", V_SENDER),
("sender-domain", V_SENDER_DOMAIN),
("sender_domain", V_SENDER_DOMAIN),
("mx", V_MX),
("helo-domain", V_HELO_DOMAIN),
("helo_domain", V_HELO_DOMAIN),
("authenticated-as", V_AUTHENTICATED_AS),
("authenticated_as", V_AUTHENTICATED_AS),
("listener", V_LISTENER),
("remote-ip", V_REMOTE_IP),
("remote_ip", V_REMOTE_IP),
("local-ip", V_LOCAL_IP),
("local_ip", V_LOCAL_IP),
("priority", V_PRIORITY),
];

View File

@@ -441,9 +441,9 @@ impl<'x> TryFrom<Variable<'x>> for MtPriority {
fn try_from(value: Variable<'x>) -> Result<Self, Self::Error> {
match value {
Variable::Integer(value) => match value {
0 => Ok(MtPriority::Mixer),
1 => Ok(MtPriority::Stanag4406),
2 => Ok(MtPriority::Nsep),
2 => Ok(MtPriority::Mixer),
3 => Ok(MtPriority::Stanag4406),
4 => Ok(MtPriority::Nsep),
_ => Err(()),
},
Variable::String(value) => MtPriority::parse_value("", &value).map_err(|_| ()),
@@ -455,9 +455,9 @@ impl<'x> TryFrom<Variable<'x>> for MtPriority {
impl From<MtPriority> for Constant {
fn from(value: MtPriority) -> Self {
Constant::Integer(match value {
MtPriority::Mixer => 0,
MtPriority::Stanag4406 => 1,
MtPriority::Nsep => 2,
MtPriority::Mixer => 2,
MtPriority::Stanag4406 => 3,
MtPriority::Nsep => 4,
})
}
}
@@ -503,10 +503,10 @@ impl<'x> TryFrom<Variable<'x>> for IpLookupStrategy {
fn try_from(value: Variable<'x>) -> Result<Self, Self::Error> {
match value {
Variable::Integer(value) => match value {
0 => Ok(IpLookupStrategy::Ipv4Only),
1 => Ok(IpLookupStrategy::Ipv6Only),
2 => Ok(IpLookupStrategy::Ipv6thenIpv4),
3 => Ok(IpLookupStrategy::Ipv4thenIpv6),
2 => Ok(IpLookupStrategy::Ipv4Only),
3 => Ok(IpLookupStrategy::Ipv6Only),
4 => Ok(IpLookupStrategy::Ipv6thenIpv4),
5 => Ok(IpLookupStrategy::Ipv4thenIpv6),
_ => Err(()),
},
Variable::String(value) => IpLookupStrategy::parse_value("", &value).map_err(|_| ()),
@@ -518,10 +518,10 @@ impl<'x> TryFrom<Variable<'x>> for IpLookupStrategy {
impl From<IpLookupStrategy> for Constant {
fn from(value: IpLookupStrategy) -> Self {
Constant::Integer(match value {
IpLookupStrategy::Ipv4Only => 0,
IpLookupStrategy::Ipv6Only => 1,
IpLookupStrategy::Ipv6thenIpv4 => 2,
IpLookupStrategy::Ipv4thenIpv6 => 3,
IpLookupStrategy::Ipv4Only => 2,
IpLookupStrategy::Ipv6Only => 3,
IpLookupStrategy::Ipv6thenIpv4 => 4,
IpLookupStrategy::Ipv4thenIpv6 => 5,
})
}
}