mirror of https://git.meli.delivery/meli/meli
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
5.1 KiB
Rust
137 lines
5.1 KiB
Rust
/*
|
|
* Copyright (c) 2020-2023, Stalwart Labs Ltd.
|
|
*
|
|
* This file is part of the Stalwart Sieve Interpreter.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
* in the LICENSE file at the top-level directory of this distribution.
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* You can be released from the requirements of the AGPLv3 license by
|
|
* purchasing a commercial license. Please contact licensing@stalw.art
|
|
* for more details.
|
|
*/
|
|
|
|
use crate::sieve::{
|
|
compiler::grammar::{test::Test, Capability},
|
|
Context, Event, Mailbox,
|
|
};
|
|
|
|
use super::RuntimeError;
|
|
|
|
pub mod comparator;
|
|
pub mod glob;
|
|
pub mod mime;
|
|
pub mod test_address;
|
|
pub mod test_body;
|
|
pub mod test_date;
|
|
pub mod test_duplicate;
|
|
pub mod test_envelope;
|
|
pub mod test_exists;
|
|
pub mod test_extlists;
|
|
pub mod test_hasflag;
|
|
pub mod test_header;
|
|
pub mod test_metadata;
|
|
pub mod test_notify;
|
|
pub mod test_size;
|
|
pub mod test_spamtest;
|
|
pub mod test_string;
|
|
|
|
pub(crate) enum TestResult {
|
|
Bool(bool),
|
|
Event { event: Event, is_not: bool },
|
|
Error(RuntimeError),
|
|
}
|
|
|
|
impl Test {
|
|
pub(crate) fn exec(&self, ctx: &mut Context) -> TestResult {
|
|
match &self {
|
|
Test::Header(test) => test.exec(ctx),
|
|
Test::Address(test) => test.exec(ctx),
|
|
Test::Envelope(test) => test.exec(ctx),
|
|
Test::Exists(test) => test.exec(ctx),
|
|
Test::Size(test) => test.exec(ctx),
|
|
Test::Body(test) => test.exec(ctx),
|
|
Test::String(test) => test.exec(ctx, false),
|
|
Test::EvalExpression(expr) => TestResult::Bool(
|
|
ctx.eval_expression(&expr.expr)
|
|
.and_then(|v| v.to_number_checked())
|
|
.unwrap_or_default()
|
|
.is_non_zero()
|
|
^ expr.is_not,
|
|
),
|
|
Test::HasFlag(test) => test.exec(ctx),
|
|
Test::Date(test) => test.exec(ctx),
|
|
Test::CurrentDate(test) => test.exec(ctx),
|
|
Test::Duplicate(test) => test.exec(ctx),
|
|
Test::NotifyMethodCapability(test) => test.exec(ctx),
|
|
Test::ValidNotifyMethod(test) => test.exec(ctx),
|
|
Test::Environment(test) => test.exec(ctx, true),
|
|
Test::ValidExtList(test) => test.exec(ctx),
|
|
Test::Ihave(test) => TestResult::Bool(
|
|
test.capabilities.iter().all(|c| {
|
|
![Capability::Variables, Capability::EncodedCharacter].contains(c)
|
|
&& ctx.runtime.allowed_capabilities.contains(c)
|
|
}) ^ test.is_not,
|
|
),
|
|
Test::MailboxExists(test) => TestResult::Event {
|
|
event: Event::MailboxExists {
|
|
mailboxes: test
|
|
.mailbox_names
|
|
.iter()
|
|
.map(|m| Mailbox::Name(ctx.eval_value(m).into_string()))
|
|
.collect(),
|
|
special_use: Vec::new(),
|
|
},
|
|
is_not: test.is_not,
|
|
},
|
|
Test::Vacation(test) => test.exec(ctx),
|
|
Test::Metadata(test) => test.exec(ctx),
|
|
Test::MetadataExists(test) => test.exec(ctx),
|
|
Test::MailboxIdExists(test) => TestResult::Event {
|
|
event: Event::MailboxExists {
|
|
mailboxes: test
|
|
.mailbox_ids
|
|
.iter()
|
|
.map(|m| Mailbox::Id(ctx.eval_value(m).into_string()))
|
|
.collect(),
|
|
special_use: Vec::new(),
|
|
},
|
|
is_not: test.is_not,
|
|
},
|
|
Test::SpamTest(test) => test.exec(ctx),
|
|
Test::VirusTest(test) => test.exec(ctx),
|
|
Test::SpecialUseExists(test) => TestResult::Event {
|
|
event: Event::MailboxExists {
|
|
mailboxes: if let Some(mailbox) = &test.mailbox {
|
|
vec![Mailbox::Name(ctx.eval_value(mailbox).into_string())]
|
|
} else {
|
|
Vec::new()
|
|
},
|
|
special_use: ctx.eval_values_owned(&test.attributes),
|
|
},
|
|
is_not: test.is_not,
|
|
},
|
|
Test::Convert(test) => test.exec(ctx),
|
|
Test::Plugin(test) => TestResult::Event {
|
|
event: ctx.eval_plugin_arguments(test),
|
|
is_not: test.is_not,
|
|
},
|
|
Test::True => TestResult::Bool(true),
|
|
Test::False => TestResult::Bool(false),
|
|
Test::Invalid(invalid) => {
|
|
TestResult::Error(RuntimeError::InvalidInstruction(invalid.clone()))
|
|
}
|
|
}
|
|
}
|
|
}
|