diff --git a/Cargo.lock b/Cargo.lock index 6d0beb1..b594293 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -228,6 +228,20 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" +[[package]] +name = "crossbeam" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845" +dependencies = [ + "cfg-if", + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + [[package]] name = "crossbeam-channel" version = "0.5.1" @@ -238,6 +252,30 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + [[package]] name = "crossbeam-queue" version = "0.3.2" @@ -880,6 +918,15 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +[[package]] +name = "memoffset" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +dependencies = [ + "autocfg", +] + [[package]] name = "minimal-lexical" version = "0.1.4" @@ -1048,6 +1095,7 @@ dependencies = [ "bitflags", "bytes", "chrono", + "crossbeam", "derivative", "derive_builder", "format-bytes", diff --git a/daemon/migrations/20211013053733_initial.up.sql b/daemon/migrations/20211013053733_initial.up.sql index 5777524..bc7e94c 100644 --- a/daemon/migrations/20211013053733_initial.up.sql +++ b/daemon/migrations/20211013053733_initial.up.sql @@ -22,4 +22,5 @@ CREATE TABLE "messages" ( "bcc" JSON, "in_reply_to" TEXT, "message_id" TEXT, + "mbox" BLOB ); diff --git a/daemon/src/lib.rs b/daemon/src/lib.rs index 53cfb35..60711e3 100644 --- a/daemon/src/lib.rs +++ b/daemon/src/lib.rs @@ -12,6 +12,8 @@ extern crate derivative; pub mod config; pub mod mail; +use std::path::PathBuf; + use anyhow::{Context, Result}; use clap::Parser; use futures::future::FutureExt; @@ -30,15 +32,15 @@ type ExitListener = oneshot::Receiver<()>; /// panorama components over Unix sockets. #[derive(Debug, Parser)] struct Options { - // /// Config file path (defaults to XDG) - // #[clap(long = "config", short = 'c')] - // config_file: Option, + /// Config file path (defaults to XDG) + #[clap(long = "config", short = 'c')] + config_file: Option, + /// Verbose mode (-v, -vv, -vvv, etc) #[clap(short = 'v', long = "verbose", parse(from_occurrences))] verbose: usize, } -#[tokio::main] pub async fn run() -> Result<()> { let opt = Options::parse(); diff --git a/daemon/src/mail/store.rs b/daemon/src/mail/store.rs index 94d747f..d7cff7e 100644 --- a/daemon/src/mail/store.rs +++ b/daemon/src/mail/store.rs @@ -10,13 +10,13 @@ pub struct MailStore { impl MailStore { /// Creates a new store tied to a SQLite database. pub async fn open(uri: impl AsRef) -> Result { - let pool = SqlitePoolOptions::new().connect(uri.as_ref()).await?; + let uri = uri.as_ref(); + let pool = SqlitePoolOptions::new().connect(uri).await?; // run migrations, if available - MIGRATOR - .run(&pool) - .await - .context("could not run migrations on the pool")?; + MIGRATOR.run(&pool).await.with_context(|| { + format!("could not run migrations on the pool at {}", uri) + })?; Ok(MailStore { pool }) } diff --git a/daemon/src/main.rs b/daemon/src/main.rs index 4f21b33..b19a5c8 100644 --- a/daemon/src/main.rs +++ b/daemon/src/main.rs @@ -1,4 +1,4 @@ use anyhow::Result; #[tokio::main] -async fn main() -> Result<()> { panorama_daemon::run() } +async fn main() -> Result<()> { panorama_daemon::run().await } diff --git a/imap/Cargo.toml b/imap/Cargo.toml index 34e072d..1b6312d 100644 --- a/imap/Cargo.toml +++ b/imap/Cargo.toml @@ -13,8 +13,9 @@ readme = "README.md" workspace = ".." [features] -default = ["rfc2177", "rfc6154"] +default = ["pool", "rfc2177", "rfc6154"] low-level = [] +pool = ["crossbeam"] rfc2087 = [] # quota rfc2177 = [] # idle rfc4315 = [] # uidplus @@ -40,6 +41,8 @@ tokio-util = { version = "0.6.8", features = ["codec"] } webpki-roots = "0.22.1" panorama-proto-common = { path = "../proto-common" } +crossbeam = { version = "0.8.1", optional = true } + # for fuzzing arbitrary = { version = "1.0.2", optional = true, features = ["derive"] } diff --git a/imap/src/client/mod.rs b/imap/src/client/mod.rs index 8192863..7e4004c 100644 --- a/imap/src/client/mod.rs +++ b/imap/src/client/mod.rs @@ -21,12 +21,14 @@ pub mod response_stream; mod client; mod codec; mod inner; +mod pool; mod tls; pub use self::client::{ ClientAuthenticated, ClientUnauthenticated, Config, ConfigBuilder, }; pub use self::codec::{ImapCodec, TaggedCommand}; +pub use self::pool::ImapPool; #[cfg(feature = "low-level")] pub use self::inner::Inner; diff --git a/imap/src/client/pool.rs b/imap/src/client/pool.rs new file mode 100644 index 0000000..38f0c4a --- /dev/null +++ b/imap/src/client/pool.rs @@ -0,0 +1,27 @@ +use std::sync::Arc; + +use crossbeam::queue::ArrayQueue; + +use super::{ClientAuthenticated, Config}; + +#[derive(Clone)] +pub struct ImapPool(Arc); + +impl ImapPool { + pub fn new(config: Config) -> Self { + let inner = InnerPool { + config, + connections: ArrayQueue::new(10), + }; + ImapPool(Arc::new(inner)) + } +} + +struct InnerPool { + config: Config, + connections: ArrayQueue, +} + +impl InnerPool { + pub fn connect() {} +}