diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index 690f454..983af5a 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -3,8 +3,8 @@ on: [push] name: CI jobs: - build_and_test: - name: Rust project + doc: + name: panorama runs-on: ubuntu-latest steps: - name: checkout diff --git a/Cargo.lock b/Cargo.lock index 2092ed2..92a865a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -649,6 +649,7 @@ dependencies = [ "inotify", "lettre", "panorama-imap", + "parking_lot", "pin-project", "rustls-connector", "serde", diff --git a/Cargo.toml b/Cargo.toml index 0a58e47..adecd74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ futures = "0.3.12" inotify = { version = "0.9.2", features = ["stream"] } lettre = "0.9.5" panorama-imap = { path = "imap", version = "0" } +parking_lot = "0.11.1" pin-project = "1.0.4" rustls-connector = "0.13.1" serde = { version = "1.0.123", features = ["derive"] } diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 7390c82..976f211 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -1,3 +1,3 @@ # Summary -- [Chapter 1](./chapter_1.md) +- [Intro](./intro.md) diff --git a/docs/src/chapter_1.md b/docs/src/chapter_1.md deleted file mode 100644 index b743fda..0000000 --- a/docs/src/chapter_1.md +++ /dev/null @@ -1 +0,0 @@ -# Chapter 1 diff --git a/docs/src/intro.md b/docs/src/intro.md new file mode 100644 index 0000000..17f0ec1 --- /dev/null +++ b/docs/src/intro.md @@ -0,0 +1,4 @@ +# Intro + +Panorama is a personal information manager. + diff --git a/src/lib.rs b/src/lib.rs index dfe41a2..aa8862b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,8 @@ //! === #![deny(missing_docs)] +// TODO: get rid of this before any kind of public release +#![allow(unused_imports)] #[macro_use] extern crate anyhow; diff --git a/src/mail/imap2.rs b/src/mail/imap2.rs index 49140c4..02b718a 100644 --- a/src/mail/imap2.rs +++ b/src/mail/imap2.rs @@ -1,14 +1,22 @@ // let's try this again +use std::collections::HashMap; use std::sync::Arc; use anyhow::Result; -use futures::stream::Stream; +use futures::{ + future::{Future, TryFuture}, + stream::Stream, +}; +use panorama_imap::builders::command::Command; +use parking_lot::Mutex; use tokio::{ io::{AsyncRead, AsyncWrite}, net::TcpStream, + sync::{oneshot, Notify}, }; use tokio_rustls::{rustls::ClientConfig, webpki::DNSNameRef, TlsConnector}; +use tokio_util::codec::{Framed, Decoder, LinesCodec}; use crate::config::{ImapConfig, TlsMethod}; @@ -25,6 +33,7 @@ pub async fn open_imap_connection(config: ImapConfig) -> Result<()> { begin_authentication(config, stream).await } TlsMethod::Starttls => { + let cmd_mgr = CommandManager::new(stream); todo!() } } @@ -48,9 +57,62 @@ async fn perform_tls_negotiation( Ok(stream) } +async fn fetch_capabilities(stream: impl AsyncRead + AsyncWrite) -> Result> { + let codec = LinesCodec::new(); + let framed = codec.framed(stream); + + // framed.send("a0 CAPABILITY"); + todo!() +} + async fn begin_authentication( config: ImapConfig, stream: impl AsyncRead + AsyncWrite, ) -> Result<()> { Ok(()) } + +trait ImapStream: AsyncRead + AsyncWrite + Unpin {} +impl ImapStream for T {} + +struct CommandManager<'a> { + id: usize, + in_flight: Arc>>>, + stream: Framed, LinesCodec>, +} + +impl<'a> CommandManager<'a> { + pub fn new(stream: impl ImapStream + 'a) -> Self { + let codec = LinesCodec::new(); + let framed = codec.framed(Box::new(stream) as Box<_>); + + CommandManager { + id: 0, + in_flight: Arc::new(Mutex::new(HashMap::new())), + stream: framed, + } + } + + pub fn decompose(self) -> impl ImapStream + 'a { + let parts = self.stream.into_parts(); + parts.io + } + + pub async fn listen(&self) { + loop { + } + } + + pub fn run(&mut self, command: Command) -> impl TryFuture { + let id = self.id; + self.id += 1; + + let (tx, rx) = oneshot::channel(); + { + let mut in_flight = self.in_flight.lock(); + in_flight.insert(id, tx); + } + + async { rx.await } + } +} diff --git a/src/main.rs b/src/main.rs index 1752dd7..3e84a0b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,6 @@ #[macro_use] extern crate tracing; -use std::fs::{File, OpenOptions}; use std::path::PathBuf; use anyhow::Result; @@ -68,8 +67,3 @@ async fn main() -> Result<()> { std::process::exit(0); // Ok(()) } - -fn setup_logger(opt: &Opt) -> Result<()> { - debug!("logging set up."); - Ok(()) -}