use crate::api::{EngineResult, SharedObject};
use rhai::plugin::{
mem, Dynamic, EvalAltResult, FnAccess, FnNamespace, ImmutableString, Module, NativeCallContext,
PluginFunction, RhaiResult, TypeId,
};
use vsmtp_common::{status::Status, Reply};
use vsmtp_plugin_vsl::objects::Object;
fn reply_or_code_id_from_object(code: &SharedObject) -> EngineResult<Reply> {
match &**code {
Object::Code(reply) => Ok(reply.clone()),
object => Err(format!("parameter must be a code, not {}", object.as_ref()).into()),
}
}
fn reply_or_code_id_from_string(code: &str) -> EngineResult<Reply> {
<Reply as std::str::FromStr>::from_str(code).map_err::<Box<EvalAltResult>, _>(|_| {
format!("parameter must be a code, not {code:?}").into()
})
}
pub use state::*;
#[rhai::plugin::export_module]
mod state {
#[must_use]
pub fn faccept() -> Status {
Status::Faccept("250 Ok\r\n".parse::<Reply>().unwrap())
}
#[doc(hidden)]
#[rhai_fn(name = "faccept", return_raw, pure)]
pub fn faccept_with_code(code: &mut SharedObject) -> EngineResult<Status> {
reply_or_code_id_from_object(code).map(Status::Faccept)
}
#[doc(hidden)]
#[rhai_fn(name = "faccept", return_raw)]
pub fn faccept_with_string(code: &str) -> EngineResult<Status> {
reply_or_code_id_from_string(code).map(Status::Faccept)
}
#[must_use]
pub fn accept() -> Status {
Status::Accept("250 Ok\r\n".parse::<Reply>().unwrap())
}
#[doc(hidden)]
#[rhai_fn(name = "accept", return_raw, pure)]
pub fn accept_with_code(code: &mut SharedObject) -> EngineResult<Status> {
reply_or_code_id_from_object(code).map(Status::Accept)
}
#[doc(hidden)]
#[rhai_fn(name = "accept", return_raw)]
pub fn accept_with_string(code: &str) -> EngineResult<Status> {
reply_or_code_id_from_string(code).map(Status::Accept)
}
#[must_use]
pub const fn next() -> Status {
Status::Next
}
#[must_use]
#[rhai_fn(global)]
pub fn deny() -> Status {
Status::Deny(
"554 permanent problems with the remote server\r\n"
.parse::<Reply>()
.unwrap(),
)
}
#[doc(hidden)]
#[rhai_fn(name = "deny", return_raw, pure)]
pub fn deny_with_code(code: &mut SharedObject) -> EngineResult<Status> {
reply_or_code_id_from_object(code).map(Status::Deny)
}
#[doc(hidden)]
#[rhai_fn(name = "deny", return_raw)]
pub fn deny_with_string(code: &str) -> EngineResult<Status> {
reply_or_code_id_from_string(code).map(Status::Deny)
}
#[must_use]
#[rhai_fn(name = "quarantine")]
pub fn quarantine_str(queue: &str) -> Status {
Status::Quarantine(queue.to_string())
}
#[rhai_fn(global, name = "==", pure)]
pub fn eq_status_operator(status_1: &mut Status, status_2: Status) -> bool {
*status_1 == status_2
}
#[rhai_fn(global, name = "!=", pure)]
pub fn neq_status_operator(status_1: &mut Status, status_2: Status) -> bool {
!(*status_1 == status_2)
}
#[rhai_fn(global, pure)]
pub fn to_string(status: &mut Status) -> String {
status.as_ref().to_string()
}
#[rhai_fn(global, pure)]
pub fn to_debug(status: &mut Status) -> String {
status.as_ref().to_string()
}
}