Skip to content

Commit

Permalink
Add support for setting envelope parts
Browse files Browse the repository at this point in the history
  • Loading branch information
mdecimus committed Jul 25, 2023
1 parent 0ab2dc8 commit cf3b2e8
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 17 deletions.
4 changes: 4 additions & 0 deletions examples/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ So if you could go ahead and try to remember to do that from now on, that'd be g
// Set to true if the script succeeded
input = false.into();
}
Event::SetEnvelope { envelope, value } => {
println!("Set envelope {envelope:?} to {value:?}");
input = true.into();
}

Event::Keep { flags, message_id } => {
println!(
Expand Down
10 changes: 8 additions & 2 deletions src/compiler/grammar/actions/action_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use crate::{
CompileError, ErrorType,
},
runtime::string::IntoString,
Envelope,
};

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
Expand All @@ -55,6 +56,7 @@ pub(crate) struct Set {
pub(crate) enum Variable {
Local(usize),
Global(String),
Envelope(Envelope),
}

impl<'x> CompilerState<'x> {
Expand Down Expand Up @@ -121,9 +123,13 @@ impl<'x> CompilerState<'x> {

pub(crate) fn register_variable(&mut self, name: String) -> Result<Variable, ErrorType> {
let name = name.to_lowercase();
if let Some((namespace, name)) = name.split_once('.') {
if let Some((namespace, part)) = name.split_once('.') {
if namespace == "global" {
Ok(Variable::Global(name.to_string()))
Ok(Variable::Global(part.to_string()))
} else if namespace == "envelope" {
Envelope::try_from(part)
.map(Variable::Envelope)
.map_err(|_| ErrorType::InvalidNamespace(namespace.to_string()))
} else {
Err(ErrorType::InvalidNamespace(namespace.to_string()))
}
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/grammar/tests/test_envelope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ impl TryFrom<String> for Envelope {

fn try_from(value: String) -> Result<Self, Self::Error> {
if let Some(envelope) = ENVELOPE.get(&value) {
Ok(envelope.clone())
Ok(*envelope)
} else {
Err(value)
}
Expand All @@ -221,7 +221,7 @@ impl<'x> TryFrom<&'x str> for Envelope {

fn try_from(value: &'x str) -> Result<Self, Self::Error> {
if let Some(envelope) = ENVELOPE.get(value) {
Ok(envelope.clone())
Ok(*envelope)
} else {
Err(value)
}
Expand Down
10 changes: 9 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@
//! // Set to true if the script succeeded
//! input = false.into();
//! }
//! Event::SetEnvelope { envelope, value } => {
//! println!("Set envelope {envelope:?} to {value:?}");
//! input = true.into();
//! }
//!
//! Event::Keep { flags, message_id } => {
//! println!(
Expand Down Expand Up @@ -378,7 +382,7 @@ pub enum Script {
Global(String),
}

#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub enum Envelope {
From,
To,
Expand Down Expand Up @@ -423,6 +427,10 @@ pub enum Event {
command: String,
arguments: Vec<String>,
},
SetEnvelope {
envelope: Envelope,
value: String,
},

// Actions
Keep {
Expand Down
8 changes: 2 additions & 6 deletions src/runtime/actions/action_flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl EditFlags {
ctx.set_variable(var_name, flags);
}
Action::Add => {
let mut new_flags = ctx.get_variable(var_name).cloned().unwrap_or_default();
let mut new_flags = ctx.get_variable(var_name).unwrap_or_default().to_string();
let mut current_flags = new_flags
.split(' ')
.map(|f| f.to_lowercase())
Expand All @@ -80,11 +80,7 @@ impl EditFlags {
let mut current_flags = Vec::new();
let mut current_flags_lc = Vec::new();

for flag in ctx
.get_variable(var_name)
.map_or("", |f| f.as_str())
.split(' ')
{
for flag in ctx.get_variable(var_name).unwrap_or_default().split(' ') {
current_flags.push(flag);
current_flags_lc.push(flag.to_lowercase());
}
Expand Down
7 changes: 7 additions & 0 deletions src/runtime/actions/action_mime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,13 @@ impl ExtractText {
Variable::Global(var_name) => {
ctx.vars_global.insert(var_name.clone(), value);
}
Variable::Envelope(env) => {
ctx.queued_events = vec![Event::SetEnvelope {
envelope: *env,
value,
}]
.into_iter();
}
}
}
}
Expand Down
22 changes: 18 additions & 4 deletions src/runtime/actions/action_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

use crate::{
compiler::grammar::actions::action_set::{Modifier, Set, Variable},
Context,
Context, Event,
};
use std::fmt::Write;

Expand Down Expand Up @@ -63,13 +63,27 @@ impl<'x> Context<'x> {
Variable::Global(var_name) => {
self.vars_global.insert(var_name.clone(), variable);
}
Variable::Envelope(env) => {
self.queued_events = vec![Event::SetEnvelope {
envelope: *env,
value: variable,
}]
.into_iter();
}
}
}

pub(crate) fn get_variable(&self, var_name: &Variable) -> Option<&String> {
pub(crate) fn get_variable(&self, var_name: &Variable) -> Option<&str> {
match var_name {
Variable::Local(var_id) => self.vars_local.get(*var_id),
Variable::Global(var_name) => self.vars_global.get(var_name),
Variable::Local(var_id) => self.vars_local.get(*var_id).map(|s| s.as_str()),
Variable::Global(var_name) => self.vars_global.get(var_name).map(|s| s.as_str()),
Variable::Envelope(env) => self.envelope.iter().find_map(|(name, val)| {
if name == env {
Some(val.as_ref())
} else {
None
}
}),
}
}
}
Expand Down
14 changes: 12 additions & 2 deletions src/runtime/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,20 @@ impl<'x> Context<'x> {
}
Instruction::Replace(replace) => replace.exec(self),
Instruction::Enclose(enclose) => enclose.exec(self),
Instruction::ExtractText(extract) => extract.exec(self),
Instruction::ExtractText(extract) => {
extract.exec(self);
if let Some(event) = self.queued_events.next() {
return Some(Ok(event));
}
}
Instruction::AddHeader(add_header) => add_header.exec(self),
Instruction::DeleteHeader(delete_header) => delete_header.exec(self),
Instruction::Set(set) => set.exec(self),
Instruction::Set(set) => {
set.exec(self);
if let Some(event) = self.queued_events.next() {
return Some(Ok(event));
}
}
Instruction::Notify(notify) => {
notify.exec(self);
if let Some(event) = self.queued_events.next() {
Expand Down
14 changes: 14 additions & 0 deletions tests/rfcs/rfc6609.json
Original file line number Diff line number Diff line change
Expand Up @@ -717,5 +717,19 @@
}
}
}
],
[
54,
{
"Set": {
"modifiers": [],
"name": {
"Envelope": "From"
},
"value": {
"Text": "test@domain.com"
}
}
}
]
]
2 changes: 2 additions & 0 deletions tests/rfcs/rfc6609.sieve
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,5 @@ if string :is "${global.i_am_on_vacation}" "1"
{
vacation "It's true, I am on vacation.";
}

set "envelope.from" "test@domain.com";

0 comments on commit cf3b2e8

Please sign in to comment.