Bootstrap from registry - part 2
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
|
||||
use common::{
|
||||
config::spamfilter::*,
|
||||
expr::{StringCow, Variable, functions::ResolveVariable},
|
||||
expr::{Expression, StringCow, Variable, functions::ResolveVariable},
|
||||
};
|
||||
use compact_str::{CompactString, ToCompactString, format_compact};
|
||||
use mail_parser::{Header, HeaderValue};
|
||||
@@ -31,25 +31,28 @@ impl<'x, T: ResolveVariable> SpamFilterResolver<'x, T> {
|
||||
}
|
||||
|
||||
impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
fn resolve_variable(&self, variable: u32) -> Variable<'_> {
|
||||
fn resolve_variable(&self, variable: ExpressionVariable) -> Variable<'_> {
|
||||
match variable {
|
||||
0..100 => self.item.resolve_variable(variable),
|
||||
V_SPAM_REMOTE_IP => self.ctx.input.remote_ip.to_compact_string().into(),
|
||||
V_SPAM_REMOTE_IP_PTR => self
|
||||
ExpressionVariable::RemoteIp => self.ctx.input.remote_ip.to_compact_string().into(),
|
||||
ExpressionVariable::RemoteIpPtr => self
|
||||
.ctx
|
||||
.output
|
||||
.iprev_ptr
|
||||
.as_deref()
|
||||
.unwrap_or_default()
|
||||
.into(),
|
||||
V_SPAM_EHLO_DOMAIN => self.ctx.output.ehlo_host.fqdn.as_str().into(),
|
||||
V_SPAM_AUTH_AS => self.ctx.input.authenticated_as.unwrap_or_default().into(),
|
||||
V_SPAM_ASN => self.ctx.input.asn.unwrap_or_default().into(),
|
||||
V_SPAM_COUNTRY => self.ctx.input.country.unwrap_or_default().into(),
|
||||
V_SPAM_IS_TLS => self.ctx.input.is_tls.into(),
|
||||
V_SPAM_ENV_FROM => self.ctx.output.env_from_addr.address.as_str().into(),
|
||||
V_SPAM_ENV_FROM_LOCAL => self.ctx.output.env_from_addr.local_part.as_str().into(),
|
||||
V_SPAM_ENV_FROM_DOMAIN => self
|
||||
ExpressionVariable::HeloDomain => self.ctx.output.ehlo_host.fqdn.as_str().into(),
|
||||
ExpressionVariable::AuthenticatedAs => {
|
||||
self.ctx.input.authenticated_as.unwrap_or_default().into()
|
||||
}
|
||||
ExpressionVariable::Asn => self.ctx.input.asn.unwrap_or_default().into(),
|
||||
ExpressionVariable::Country => self.ctx.input.country.unwrap_or_default().into(),
|
||||
ExpressionVariable::IsTls => self.ctx.input.is_tls.into(),
|
||||
ExpressionVariable::EnvFrom => self.ctx.output.env_from_addr.address.as_str().into(),
|
||||
ExpressionVariable::EnvFromLocal => {
|
||||
self.ctx.output.env_from_addr.local_part.as_str().into()
|
||||
}
|
||||
ExpressionVariable::EnvFromDomain => self
|
||||
.ctx
|
||||
.output
|
||||
.env_from_addr
|
||||
@@ -57,7 +60,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.fqdn
|
||||
.as_str()
|
||||
.into(),
|
||||
V_SPAM_ENV_TO => self
|
||||
ExpressionVariable::EnvTo => self
|
||||
.ctx
|
||||
.output
|
||||
.env_to_addr
|
||||
@@ -65,8 +68,8 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.map(|e| Variable::from(e.address.as_str()))
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
V_SPAM_FROM => self.ctx.output.from.email.address.as_str().into(),
|
||||
V_SPAM_FROM_NAME => self
|
||||
ExpressionVariable::From => self.ctx.output.from.email.address.as_str().into(),
|
||||
ExpressionVariable::FromName => self
|
||||
.ctx
|
||||
.output
|
||||
.from
|
||||
@@ -74,9 +77,11 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.as_deref()
|
||||
.unwrap_or_default()
|
||||
.into(),
|
||||
V_SPAM_FROM_LOCAL => self.ctx.output.from.email.local_part.as_str().into(),
|
||||
V_SPAM_FROM_DOMAIN => self.ctx.output.from.email.domain_part.fqdn.as_str().into(),
|
||||
V_SPAM_REPLY_TO => self
|
||||
ExpressionVariable::FromLocal => self.ctx.output.from.email.local_part.as_str().into(),
|
||||
ExpressionVariable::FromDomain => {
|
||||
self.ctx.output.from.email.domain_part.fqdn.as_str().into()
|
||||
}
|
||||
ExpressionVariable::ReplyTo => self
|
||||
.ctx
|
||||
.output
|
||||
.reply_to
|
||||
@@ -84,7 +89,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.map(|r| r.email.address.as_str())
|
||||
.unwrap_or_default()
|
||||
.into(),
|
||||
V_SPAM_REPLY_TO_NAME => self
|
||||
ExpressionVariable::ReplyToName => self
|
||||
.ctx
|
||||
.output
|
||||
.reply_to
|
||||
@@ -92,7 +97,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.and_then(|r| r.name.as_deref())
|
||||
.unwrap_or_default()
|
||||
.into(),
|
||||
V_SPAM_REPLY_TO_LOCAL => self
|
||||
ExpressionVariable::ReplyToLocal => self
|
||||
.ctx
|
||||
.output
|
||||
.reply_to
|
||||
@@ -100,7 +105,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.map(|r| r.email.local_part.as_str())
|
||||
.unwrap_or_default()
|
||||
.into(),
|
||||
V_SPAM_REPLY_TO_DOMAIN => self
|
||||
ExpressionVariable::ReplyToDomain => self
|
||||
.ctx
|
||||
.output
|
||||
.reply_to
|
||||
@@ -108,7 +113,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.map(|r| r.email.domain_part.fqdn.as_str())
|
||||
.unwrap_or_default()
|
||||
.into(),
|
||||
V_SPAM_TO => self
|
||||
ExpressionVariable::To => self
|
||||
.ctx
|
||||
.output
|
||||
.recipients_to
|
||||
@@ -116,7 +121,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.map(|r| Variable::from(r.email.address.as_str()))
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
V_SPAM_TO_NAME => self
|
||||
ExpressionVariable::ToName => self
|
||||
.ctx
|
||||
.output
|
||||
.recipients_to
|
||||
@@ -124,7 +129,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.filter_map(|r| Variable::from(r.name.as_deref()?).into())
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
V_SPAM_TO_LOCAL => self
|
||||
ExpressionVariable::ToLocal => self
|
||||
.ctx
|
||||
.output
|
||||
.recipients_to
|
||||
@@ -132,7 +137,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.map(|r| Variable::from(r.email.local_part.as_str()))
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
V_SPAM_TO_DOMAIN => self
|
||||
ExpressionVariable::ToDomain => self
|
||||
.ctx
|
||||
.output
|
||||
.recipients_to
|
||||
@@ -140,7 +145,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.map(|r| Variable::from(r.email.domain_part.fqdn.as_str()))
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
V_SPAM_CC => self
|
||||
ExpressionVariable::Cc => self
|
||||
.ctx
|
||||
.output
|
||||
.recipients_cc
|
||||
@@ -148,7 +153,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.map(|r| Variable::from(r.email.address.as_str()))
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
V_SPAM_CC_NAME => self
|
||||
ExpressionVariable::CcName => self
|
||||
.ctx
|
||||
.output
|
||||
.recipients_cc
|
||||
@@ -156,7 +161,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.filter_map(|r| Variable::from(r.name.as_deref()?).into())
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
V_SPAM_CC_LOCAL => self
|
||||
ExpressionVariable::CcLocal => self
|
||||
.ctx
|
||||
.output
|
||||
.recipients_cc
|
||||
@@ -164,7 +169,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.map(|r| Variable::from(r.email.local_part.as_str()))
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
V_SPAM_CC_DOMAIN => self
|
||||
ExpressionVariable::CcDomain => self
|
||||
.ctx
|
||||
.output
|
||||
.recipients_cc
|
||||
@@ -172,7 +177,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.map(|r| Variable::from(r.email.domain_part.fqdn.as_str()))
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
V_SPAM_BCC => self
|
||||
ExpressionVariable::Bcc => self
|
||||
.ctx
|
||||
.output
|
||||
.recipients_bcc
|
||||
@@ -180,7 +185,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.map(|r| Variable::from(r.email.address.as_str()))
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
V_SPAM_BCC_NAME => self
|
||||
ExpressionVariable::BccName => self
|
||||
.ctx
|
||||
.output
|
||||
.recipients_bcc
|
||||
@@ -188,7 +193,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.filter_map(|r| Variable::from(r.name.as_deref()?).into())
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
V_SPAM_BCC_LOCAL => self
|
||||
ExpressionVariable::BccLocal => self
|
||||
.ctx
|
||||
.output
|
||||
.recipients_bcc
|
||||
@@ -196,7 +201,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.map(|r| Variable::from(r.email.local_part.as_str()))
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
V_SPAM_BCC_DOMAIN => self
|
||||
ExpressionVariable::BccDomain => self
|
||||
.ctx
|
||||
.output
|
||||
.recipients_bcc
|
||||
@@ -204,8 +209,10 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
.map(|r| Variable::from(r.email.domain_part.fqdn.as_str()))
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
V_SPAM_BODY_TEXT => self.ctx.text_body().unwrap_or_default().into(),
|
||||
V_SPAM_BODY_HTML => self
|
||||
ExpressionVariable::Body | ExpressionVariable::BodyText => {
|
||||
self.ctx.text_body().unwrap_or_default().into()
|
||||
}
|
||||
ExpressionVariable::BodyHtml => self
|
||||
.ctx
|
||||
.input
|
||||
.message
|
||||
@@ -221,13 +228,13 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
})
|
||||
.unwrap_or_default()
|
||||
.into(),
|
||||
V_SPAM_BODY_RAW => Variable::from(CompactString::from_utf8_lossy(
|
||||
ExpressionVariable::BodyRaw => Variable::from(CompactString::from_utf8_lossy(
|
||||
self.ctx.input.message.raw_message(),
|
||||
)),
|
||||
V_SPAM_SUBJECT => self.ctx.output.subject_lc.as_str().into(),
|
||||
V_SPAM_SUBJECT_THREAD => self.ctx.output.subject_thread_lc.as_str().into(),
|
||||
V_SPAM_LOCATION => self.location.as_str().into(),
|
||||
V_WORDS_SUBJECT => self
|
||||
ExpressionVariable::Subject => self.ctx.output.subject_lc.as_str().into(),
|
||||
ExpressionVariable::SubjectThread => self.ctx.output.subject_thread_lc.as_str().into(),
|
||||
ExpressionVariable::Location => self.location.as_str().into(),
|
||||
ExpressionVariable::SubjectWords => self
|
||||
.ctx
|
||||
.output
|
||||
.subject_tokens
|
||||
@@ -241,7 +248,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.into(),
|
||||
V_WORDS_BODY => self
|
||||
ExpressionVariable::BodyWords => self
|
||||
.ctx
|
||||
.input
|
||||
.message
|
||||
@@ -263,7 +270,7 @@ impl<T: ResolveVariable> ResolveVariable for SpamFilterResolver<'_, T> {
|
||||
})
|
||||
.unwrap_or_default()
|
||||
.into(),
|
||||
_ => Variable::Integer(0),
|
||||
variable => self.item.resolve_variable(variable),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,13 +285,17 @@ pub(crate) struct EmailHeader<'x> {
|
||||
}
|
||||
|
||||
impl ResolveVariable for EmailHeader<'_> {
|
||||
fn resolve_variable(&self, variable: u32) -> Variable<'_> {
|
||||
fn resolve_variable(&self, variable: ExpressionVariable) -> Variable<'_> {
|
||||
match variable {
|
||||
V_HEADER_NAME => self.header.name().into(),
|
||||
V_HEADER_NAME_LOWER => CompactString::from_str_to_lowercase(self.header.name()).into(),
|
||||
V_HEADER_VALUE | V_HEADER_VALUE_LOWER | V_HEADER_PROPERTY => match &self.header.value {
|
||||
ExpressionVariable::Name => self.header.name().into(),
|
||||
ExpressionVariable::NameLower => {
|
||||
CompactString::from_str_to_lowercase(self.header.name()).into()
|
||||
}
|
||||
ExpressionVariable::Value
|
||||
| ExpressionVariable::ValueLower
|
||||
| ExpressionVariable::Attributes => match &self.header.value {
|
||||
HeaderValue::Text(text) => {
|
||||
if variable == V_HEADER_VALUE_LOWER {
|
||||
if variable == ExpressionVariable::ValueLower {
|
||||
CompactString::from_str_to_lowercase(text).into()
|
||||
} else {
|
||||
text.as_ref().into()
|
||||
@@ -293,7 +304,7 @@ impl ResolveVariable for EmailHeader<'_> {
|
||||
HeaderValue::TextList(list) => Variable::Array(
|
||||
list.iter()
|
||||
.map(|text| {
|
||||
Variable::String(if variable == V_HEADER_VALUE_LOWER {
|
||||
Variable::String(if variable == ExpressionVariable::ValueLower {
|
||||
StringCow::Owned(CompactString::from_str_to_lowercase(text))
|
||||
} else {
|
||||
StringCow::Borrowed(text.as_ref())
|
||||
@@ -306,7 +317,7 @@ impl ResolveVariable for EmailHeader<'_> {
|
||||
.iter()
|
||||
.filter_map(|a| {
|
||||
a.address.as_ref().map(|text| {
|
||||
Variable::String(if variable == V_HEADER_VALUE_LOWER {
|
||||
Variable::String(if variable == ExpressionVariable::ValueLower {
|
||||
StringCow::Owned(CompactString::from_str_to_lowercase(text))
|
||||
} else {
|
||||
StringCow::Borrowed(text.as_ref())
|
||||
@@ -319,7 +330,7 @@ impl ResolveVariable for EmailHeader<'_> {
|
||||
.iter()
|
||||
.filter_map(|a| {
|
||||
a.name.as_ref().map(|text| {
|
||||
Variable::String(if variable == V_HEADER_VALUE_LOWER {
|
||||
Variable::String(if variable == ExpressionVariable::ValueLower {
|
||||
StringCow::Owned(CompactString::from_str_to_lowercase(text))
|
||||
} else {
|
||||
StringCow::Borrowed(text.as_ref())
|
||||
@@ -332,7 +343,7 @@ impl ResolveVariable for EmailHeader<'_> {
|
||||
CompactString::new(date_time.to_rfc3339()).into()
|
||||
}
|
||||
HeaderValue::ContentType(ct) => {
|
||||
if variable != V_HEADER_PROPERTY {
|
||||
if variable != ExpressionVariable::Attributes {
|
||||
if let Some(st) = ct.subtype() {
|
||||
format_compact!("{}/{}", ct.ctype(), st).into()
|
||||
} else {
|
||||
@@ -355,7 +366,7 @@ impl ResolveVariable for EmailHeader<'_> {
|
||||
}
|
||||
}
|
||||
HeaderValue::Received(_) => {
|
||||
if variable == V_HEADER_VALUE_LOWER {
|
||||
if variable == ExpressionVariable::ValueLower {
|
||||
CompactString::from_str_to_lowercase(self.raw.trim()).into()
|
||||
} else {
|
||||
self.raw.trim().into()
|
||||
@@ -363,8 +374,8 @@ impl ResolveVariable for EmailHeader<'_> {
|
||||
}
|
||||
HeaderValue::Empty => "".into(),
|
||||
},
|
||||
V_HEADER_RAW => self.raw.into(),
|
||||
V_HEADER_RAW_LOWER => CompactString::from_str_to_lowercase(self.raw).into(),
|
||||
ExpressionVariable::Raw => self.raw.into(),
|
||||
ExpressionVariable::RawLower => CompactString::from_str_to_lowercase(self.raw).into(),
|
||||
_ => Variable::Integer(0),
|
||||
}
|
||||
}
|
||||
@@ -375,13 +386,15 @@ impl ResolveVariable for EmailHeader<'_> {
|
||||
}
|
||||
|
||||
impl ResolveVariable for Recipient {
|
||||
fn resolve_variable(&self, variable: u32) -> Variable<'_> {
|
||||
fn resolve_variable(&self, variable: ExpressionVariable) -> Variable<'_> {
|
||||
match variable {
|
||||
V_RCPT_EMAIL => Variable::from(self.email.address.as_str()),
|
||||
V_RCPT_NAME => Variable::from(self.name.as_deref().unwrap_or_default()),
|
||||
V_RCPT_LOCAL => Variable::from(self.email.local_part.as_str()),
|
||||
V_RCPT_DOMAIN => Variable::from(self.email.domain_part.fqdn.as_str()),
|
||||
V_RCPT_DOMAIN_SLD => Variable::from(self.email.domain_part.sld_or_default()),
|
||||
ExpressionVariable::Email | ExpressionVariable::Value => {
|
||||
Variable::from(self.email.address.as_str())
|
||||
}
|
||||
ExpressionVariable::Name => Variable::from(self.name.as_deref().unwrap_or_default()),
|
||||
ExpressionVariable::Local => Variable::from(self.email.local_part.as_str()),
|
||||
ExpressionVariable::Domain => Variable::from(self.email.domain_part.fqdn.as_str()),
|
||||
ExpressionVariable::Sld => Variable::from(self.email.domain_part.sld_or_default()),
|
||||
_ => Variable::Integer(0),
|
||||
}
|
||||
}
|
||||
@@ -392,52 +405,54 @@ impl ResolveVariable for Recipient {
|
||||
}
|
||||
|
||||
impl ResolveVariable for UrlParts<'_> {
|
||||
fn resolve_variable(&self, variable: u32) -> Variable<'_> {
|
||||
fn resolve_variable(&self, variable: ExpressionVariable) -> Variable<'_> {
|
||||
match variable {
|
||||
V_URL_FULL => Variable::from(self.url.as_str()),
|
||||
V_URL_PATH_QUERY => Variable::from(
|
||||
ExpressionVariable::Url | ExpressionVariable::Value => {
|
||||
Variable::from(self.url.as_str())
|
||||
}
|
||||
ExpressionVariable::PathQuery => Variable::from(
|
||||
self.url_parsed
|
||||
.as_ref()
|
||||
.and_then(|p| p.parts.path_and_query().map(|p| p.as_str()))
|
||||
.unwrap_or_default(),
|
||||
),
|
||||
V_URL_PATH => Variable::from(
|
||||
ExpressionVariable::UrlPath => Variable::from(
|
||||
self.url_parsed
|
||||
.as_ref()
|
||||
.map(|p| p.parts.path())
|
||||
.unwrap_or_default(),
|
||||
),
|
||||
V_URL_QUERY => Variable::from(
|
||||
ExpressionVariable::Query => Variable::from(
|
||||
self.url_parsed
|
||||
.as_ref()
|
||||
.and_then(|p| p.parts.query())
|
||||
.unwrap_or_default(),
|
||||
),
|
||||
V_URL_SCHEME => Variable::from(
|
||||
ExpressionVariable::Scheme => Variable::from(
|
||||
self.url_parsed
|
||||
.as_ref()
|
||||
.and_then(|p| p.parts.scheme_str())
|
||||
.unwrap_or_default(),
|
||||
),
|
||||
V_URL_AUTHORITY => Variable::from(
|
||||
ExpressionVariable::Authority => Variable::from(
|
||||
self.url_parsed
|
||||
.as_ref()
|
||||
.and_then(|p| p.parts.authority().map(|a| a.as_str()))
|
||||
.unwrap_or_default(),
|
||||
),
|
||||
V_URL_HOST => Variable::from(
|
||||
ExpressionVariable::Host => Variable::from(
|
||||
self.url_parsed
|
||||
.as_ref()
|
||||
.map(|p| p.host.fqdn.as_str())
|
||||
.unwrap_or_default(),
|
||||
),
|
||||
V_URL_HOST_SLD => Variable::from(
|
||||
ExpressionVariable::Sld => Variable::from(
|
||||
self.url_parsed
|
||||
.as_ref()
|
||||
.map(|p| p.host.sld_or_default())
|
||||
.unwrap_or_default(),
|
||||
),
|
||||
V_URL_PORT => Variable::Integer(
|
||||
ExpressionVariable::Port => Variable::Integer(
|
||||
self.url_parsed
|
||||
.as_ref()
|
||||
.and_then(|p| p.parts.port_u16())
|
||||
@@ -455,7 +470,7 @@ impl ResolveVariable for UrlParts<'_> {
|
||||
pub struct StringResolver<'x>(pub &'x str);
|
||||
|
||||
impl ResolveVariable for StringResolver<'_> {
|
||||
fn resolve_variable(&self, _: u32) -> Variable<'_> {
|
||||
fn resolve_variable(&self, _: ExpressionVariable) -> Variable<'_> {
|
||||
Variable::from(self.0)
|
||||
}
|
||||
|
||||
@@ -467,7 +482,7 @@ impl ResolveVariable for StringResolver<'_> {
|
||||
pub struct StringListResolver<'x>(pub &'x [String]);
|
||||
|
||||
impl ResolveVariable for StringListResolver<'_> {
|
||||
fn resolve_variable(&self, _: u32) -> Variable<'_> {
|
||||
fn resolve_variable(&self, _: ExpressionVariable) -> Variable<'_> {
|
||||
Variable::Array(self.0.iter().map(|v| Variable::from(v.as_str())).collect())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user