start maildir work
This commit is contained in:
parent
f906e5203b
commit
680c9c9ebc
7 changed files with 93 additions and 20 deletions
26
Cargo.lock
generated
26
Cargo.lock
generated
|
@ -32,9 +32,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.38"
|
version = "1.0.39"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
|
checksum = "81cddc5f91628367664cc7c69714ff08deee8a3efc54623011c772544d7b2767"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "archery"
|
name = "archery"
|
||||||
|
@ -1481,9 +1481,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.89"
|
version = "0.2.90"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "538c092e5586f4cdd7dd8078c4a79220e3e168880218124dcbce860f0ea938c6"
|
checksum = "ba4aede83fc3617411dc6993bc8c70919750c1c257c6ca6a502aed6e0e2394ae"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libgit2-sys"
|
name = "libgit2-sys"
|
||||||
|
@ -1860,6 +1860,16 @@ dependencies = [
|
||||||
"webpki-roots",
|
"webpki-roots",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "panorama-maildir"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"futures 0.3.13",
|
||||||
|
"tempfile",
|
||||||
|
"tokio 1.3.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "panorama-smtp"
|
name = "panorama-smtp"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -2486,9 +2496,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "siphasher"
|
name = "siphasher"
|
||||||
version = "0.3.3"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7"
|
checksum = "cbce6d4507c7e4a3962091436e56e95290cb71fa302d0d270e32130b75fbff27"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sized-chunks"
|
name = "sized-chunks"
|
||||||
|
@ -2939,9 +2949,9 @@ checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vec-arena"
|
name = "vec-arena"
|
||||||
version = "1.0.0"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eafc1b9b2dfc6f5529177b62cf806484db55b32dc7c9658a118e11bbeb33061d"
|
checksum = "34b2f665b594b07095e3ac3f718e13c2197143416fae4c5706cffb7b1af8d7f1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vec_map"
|
name = "vec_map"
|
||||||
|
|
|
@ -9,10 +9,14 @@ readme = "README.md"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["imap", "smtp"]
|
members = [
|
||||||
|
"imap",
|
||||||
|
"smtp",
|
||||||
|
"maildir",
|
||||||
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.38"
|
anyhow = "1.0.39"
|
||||||
async-trait = "0.1.48"
|
async-trait = "0.1.48"
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
chrono = "0.4.19"
|
chrono = "0.4.19"
|
||||||
|
|
11
maildir/Cargo.toml
Normal file
11
maildir/Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[package]
|
||||||
|
name = "panorama-maildir"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Michael Zhang <mail@mzhang.io>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = "1.0.39"
|
||||||
|
futures = "0.3.13"
|
||||||
|
tempfile = "3.2.0"
|
||||||
|
tokio = { version = "1.3.0", features = ["full"] }
|
50
maildir/src/lib.rs
Normal file
50
maildir/src/lib.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use tokio::fs::{File, self};
|
||||||
|
use anyhow::Result;
|
||||||
|
use tempfile::NamedTempFile;
|
||||||
|
|
||||||
|
pub struct Maildir {
|
||||||
|
path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Maildir {
|
||||||
|
// TODO: should this double as create (aka create tmp cur new if they don't exist)?
|
||||||
|
pub async fn open(path: impl AsRef<Path>) -> Result<Self> {
|
||||||
|
Ok(Maildir {
|
||||||
|
path: path.as_ref().to_path_buf(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stores a new message into the `new` directory
|
||||||
|
// TODO: maybe have a streaming option?
|
||||||
|
pub async fn store(&self) -> Result<()> {
|
||||||
|
let unique_name = "hellosu";
|
||||||
|
let tmp_file = self.tmp_dir().join(unique_name);
|
||||||
|
{
|
||||||
|
let mut file = File::create(&tmp_file).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_file = self.new_dir().join(unique_name);
|
||||||
|
fs::rename(tmp_file, new_file).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the path to the `tmp` subdirectory
|
||||||
|
#[inline]
|
||||||
|
pub fn tmp_dir(&self) -> PathBuf {
|
||||||
|
self.path.join("tmp")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the path to the `new` subdirectory
|
||||||
|
#[inline]
|
||||||
|
pub fn new_dir(&self) -> PathBuf {
|
||||||
|
self.path.join("new")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the path to the `cur` subdirectory
|
||||||
|
#[inline]
|
||||||
|
pub fn cur_dir(&self) -> PathBuf {
|
||||||
|
self.path.join("cur")
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,11 +10,11 @@ pub struct ColonPrompt {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColonPrompt {
|
impl ColonPrompt {
|
||||||
pub fn init(term: TermType) -> Self {
|
pub fn init(term: TermType) -> Result<Self> {
|
||||||
let s = term.size().unwrap();
|
let s = term.size()?;
|
||||||
term.set_cursor(1, s.height - 1);
|
term.set_cursor(1, s.height - 1)?;
|
||||||
term.show_cursor();
|
term.show_cursor()?;
|
||||||
ColonPrompt::default()
|
Ok(ColonPrompt::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ impl HandlesInput for BaseInputHandler {
|
||||||
KeyCode::Char('j') => self.1.store(1, Ordering::Relaxed),
|
KeyCode::Char('j') => self.1.store(1, Ordering::Relaxed),
|
||||||
KeyCode::Char('k') => self.1.store(-1, Ordering::Relaxed),
|
KeyCode::Char('k') => self.1.store(-1, Ordering::Relaxed),
|
||||||
KeyCode::Char(':') => {
|
KeyCode::Char(':') => {
|
||||||
let colon_prompt = Box::new(ColonPrompt::init(term));
|
let colon_prompt = Box::new(ColonPrompt::init(term)?);
|
||||||
return Ok(InputResult::Push(colon_prompt));
|
return Ok(InputResult::Push(colon_prompt));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -286,16 +286,14 @@ pub async fn run_ui(
|
||||||
// handle states in the state stack
|
// handle states in the state stack
|
||||||
// although this is written in a for loop, every case except one should break
|
// although this is written in a for loop, every case except one should break
|
||||||
let mut should_pop = false;
|
let mut should_pop = false;
|
||||||
for input_state in input_states.iter_mut().rev() {
|
if let Some(input_state) = input_states.last_mut() {
|
||||||
match input_state.handle_key(&mut term, evt)? {
|
match input_state.handle_key(&mut term, evt)? {
|
||||||
InputResult::Ok => break,
|
InputResult::Ok => {},
|
||||||
InputResult::Push(state) => {
|
InputResult::Push(state) => {
|
||||||
input_states.push(state);
|
input_states.push(state);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
InputResult::Pop => {
|
InputResult::Pop => {
|
||||||
should_pop = true;
|
should_pop = true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue