diff --git a/Cargo.lock b/Cargo.lock index 8e245250..5b2065bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,12 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" - [[package]] name = "addr2line" version = "0.19.0" @@ -75,12 +69,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "aliasable" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" - [[package]] name = "amq-protocol" version = "7.1.2" @@ -2179,7 +2167,6 @@ dependencies = [ "mod-sqlite", "nix 0.26.2", "once_cell", - "ouroboros", "ppp", "prometheus", "rand 0.8.5", @@ -2187,6 +2174,7 @@ dependencies = [ "rfc5321", "rustls 0.20.8", "rustls-pemfile", + "self_cell 1.0.0", "serde", "serde_json", "socksv5", @@ -2677,7 +2665,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2819be6b8bd3236f0fdbf86b1ff2d1f42ef8ef939eed74f6bc3ecf2e6344cd96" dependencies = [ "memo-map", - "self_cell", + "self_cell 0.10.2", "serde", ] @@ -3011,29 +2999,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "ouroboros" -version = "0.15.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1358bd1558bd2a083fed428ffeda486fbfb323e698cdda7794259d592ca72db" -dependencies = [ - "aliasable", - "ouroboros_macro", -] - -[[package]] -name = "ouroboros_macro" -version = "0.15.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f7d21ccd03305a674437ee1248f3ab5d4b1db095cf1caf49f1713ddf61956b7" -dependencies = [ - "Inflector", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "overload" version = "0.1.1" @@ -3358,30 +3323,6 @@ dependencies = [ "syn 2.0.18", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" version = "1.0.60" @@ -4072,6 +4013,12 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af" +[[package]] +name = "self_cell" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3926e239738d36060909ffe6f511502f92149a45a1fade7fe031cb2d33e88b" + [[package]] name = "serde" version = "1.0.164" diff --git a/crates/kumod/Cargo.toml b/crates/kumod/Cargo.toml index 0294528a..db0951ff 100644 --- a/crates/kumod/Cargo.toml +++ b/crates/kumod/Cargo.toml @@ -54,7 +54,6 @@ mod-redis = {path="../mod-redis"} mod-sqlite = {path="../mod-sqlite"} nix = {version="0.26", features=["resource"]} once_cell = "1.17" -ouroboros = "0.15" ppp = "2.2" prometheus = "0.13" rand = "0.8" @@ -64,6 +63,7 @@ rustls = "0.20" rustls-pemfile = "1.0" serde = {version="1.0", features=["derive"]} humantime-serde = "1.1" +self_cell = "1.0" serde_json = "1.0" socksv5 = {version="0.3", default-features=false, features=["tokio"]} spool = {path="../spool"} diff --git a/crates/kumod/src/http_server/inject_v1.rs b/crates/kumod/src/http_server/inject_v1.rs index 78b4030c..72eac6e0 100644 --- a/crates/kumod/src/http_server/inject_v1.rs +++ b/crates/kumod/src/http_server/inject_v1.rs @@ -13,8 +13,8 @@ use mail_builder::headers::HeaderType; use mail_builder::mime::MimePart; use message::EnvelopeAddress; use minijinja::{Environment, Template}; -use ouroboros::self_referencing; use rfc5321::Response; +use self_cell::self_cell; use serde::{Deserialize, Serialize}; use serde_json::Value; use spool::SpoolId; @@ -97,12 +97,18 @@ pub struct Attachment { base64: bool, } -#[self_referencing] +type TemplateList<'a> = Vec>; + +self_cell!( + struct CompiledTemplates<'a> { + owner: Environment<'a>, + #[covariant] + dependent: TemplateList, + } +); + struct Compiled<'a> { - env: Environment<'a>, - #[borrows(env)] - #[covariant] - templates: Vec>, + env_and_templates: CompiledTemplates<'a>, inline: Vec>, attached: Vec>, } @@ -135,7 +141,7 @@ impl<'a> Compiled<'a> { let mut id = 0; match content { - Content::Rfc822(_) => Ok(self.borrow_templates()[id].render(&subst)?), + Content::Rfc822(_) => Ok(self.env_and_templates.borrow_dependent()[id].render(&subst)?), Content::Builder { text_body, html_body, @@ -151,14 +157,14 @@ impl<'a> Compiled<'a> { if text_body.is_some() { text.replace(MimePart::new_text( - self.borrow_templates()[id].render(&subst)?, + self.env_and_templates.borrow_dependent()[id].render(&subst)?, )); id += 1; } if html_body.is_some() { html.replace(MimePart::new_html( - self.borrow_templates()[id].render(&subst)?, + self.env_and_templates.borrow_dependent()[id].render(&subst)?, )); id += 1; } @@ -184,7 +190,7 @@ impl<'a> Compiled<'a> { } for (name, _value) in headers { - let expanded = self.borrow_templates()[id].render(&subst)?; + let expanded = self.env_and_templates.borrow_dependent()[id].render(&subst)?; id += 1; builder = builder.header( name.to_string(), @@ -192,9 +198,6 @@ impl<'a> Compiled<'a> { ); } - let attached = self.borrow_attached(); - let inline = self.borrow_inline(); - let content_node = match (text, html) { (Some(t), Some(h)) => { MimePart::new_multipart("multipart/alternative", vec![t, h]) @@ -204,19 +207,19 @@ impl<'a> Compiled<'a> { (None, None) => anyhow::bail!("refusing to send an empty message"), }; - let content_node = if !inline.is_empty() { - let mut parts = Vec::with_capacity(inline.len() + 1); + let content_node = if !self.inline.is_empty() { + let mut parts = Vec::with_capacity(self.inline.len() + 1); parts.push(content_node); - parts.extend(inline.iter().cloned()); + parts.extend(self.inline.iter().cloned()); MimePart::new_multipart("multipart/related", parts) } else { content_node }; - let root = if !attached.is_empty() { - let mut parts = Vec::with_capacity(attached.len() + 1); + let root = if !self.attached.is_empty() { + let mut parts = Vec::with_capacity(self.attached.len() + 1); parts.push(content_node); - parts.extend(attached.iter().cloned()); + parts.extend(self.attached.iter().cloned()); MimePart::new_multipart("multipart/mixed", parts) } else { @@ -301,7 +304,7 @@ impl InjectV1Request { fn get_templates<'b>( env: &'b Environment, content: &Content, - ) -> anyhow::Result>> { + ) -> anyhow::Result> { let mut id = 0; let mut templates = vec![]; match content { @@ -338,13 +341,14 @@ impl InjectV1Request { let (inline, attached) = self.attachment_data()?; - Ok(CompiledTryBuilder { - env, + let env_and_templates = + CompiledTemplates::try_new(env, |env: &Environment| get_templates(env, &self.content))?; + + Ok(Compiled { + env_and_templates, inline, attached, - templates_builder: |env: &Environment| get_templates(env, &self.content), - } - .try_build()?) + }) } fn attachment_data(&self) -> anyhow::Result<(Vec, Vec)> {