use std::fs::remove_file;
use std::process::{Command, Stdio};
use serde::{Deserialize, Serialize};
use crate::error::Error::*;
use crate::error::*;
use crate::Value;
use crate::Value::*;
use notmuch::{Database, Message};
#[derive(Debug, Serialize, Deserialize, Default)]
#[serde(deny_unknown_fields)]
pub struct Operations {
pub rm: Option<Value>,
pub add: Option<Value>,
pub run: Option<Vec<String>>,
pub del: Option<bool>,
}
impl Operations {
pub fn apply(&self, msg: &Message, db: &Database, name: &str) -> Result<bool> {
if let Some(rm) = &self.rm {
match rm {
Single(tag) => {
msg.remove_tag(tag)?;
}
Multiple(tags) => {
for tag in tags {
msg.remove_tag(tag)?;
}
}
Bool(all) => {
if *all {
msg.remove_all_tags()?;
}
}
}
}
if let Some(add) = &self.add {
match add {
Single(tag) => {
msg.add_tag(tag)?;
}
Multiple(tags) => {
for tag in tags {
msg.add_tag(tag)?;
}
}
Bool(_) => {
let e = "'add' operation doesn't support bool types".to_string();
return Err(UnsupportedValue(e));
}
}
}
if let Some(argv) = &self.run {
Command::new(&argv[0])
.args(&argv[1..])
.stdout(Stdio::inherit())
.env("NOTCOAL_FILE_NAME", msg.filename())
.env("NOTCOAL_MSG_ID", msg.id().as_ref())
.env("NOTCOAL_FILTER_NAME", name)
.spawn()?;
}
if let Some(del) = &self.del {
if *del {
remove_file(msg.filename())?;
db.remove_message(msg.filename())?;
return Ok(true);
}
}
Ok(false)
}
}