Skip to content

pimalaya/io-maildir

I/O Maildir Documentation Matrix Mastodon

I/O-free Maildir library written in Rust

This library provides I/O-agnostic coroutines to manage Maildir filesystems, based on io-fs. It is built on three concepts:

Coroutine

A coroutine is an I/O-free, resumable and composable state machine. It emits I/O requests without performing any I/O itself, and receives I/O responses to make progress. A coroutine is terminated when it stops emitting I/O requests.

See available coroutines at ./src/coroutines.

Runtime

A runtime contains all the I/O logic. It is responsible for processing I/O requests and returning the corresponding I/O responses. Runtimes are provided by io-fs.

See available runtimes at io-fs.

Loop

The loop is the glue between coroutines and runtimes. It drives the coroutine forward by feeding each FsOutput back as the next argument, until the coroutine terminates.

Examples

Create a Maildir and store a message (blocking)

use std::path::PathBuf;

use io_fs::runtimes::std::handle;
use io_maildir::{
    coroutines::{
        maildir_create::{MaildirCreate, MaildirCreateResult},
        message_store::{MaildirMessageStore, MaildirMessageStoreResult},
    },
    flag::Flags,
    maildir::{Maildir, MaildirSubdir},
};

let root = PathBuf::from("/path/to/maildir");

// create the Maildir structure (root, cur, new, tmp)

let mut arg = None;
let mut create = MaildirCreate::new(root.clone());

loop {
    match create.resume(arg.take()) {
        MaildirCreateResult::Ok => break,
        MaildirCreateResult::Io(input) => arg = Some(handle(input).unwrap()),
        MaildirCreateResult::Err(err) => panic!("{err}"),
    }
}

let maildir = Maildir::try_from(root).unwrap();

// store a message in /new

let contents = b"From: alice@example.com\r\nSubject: Hello\r\n\r\nHello!\r\n".to_vec();

let mut arg = None;
let mut store = MaildirMessageStore::new(
    maildir,
    MaildirSubdir::New,
    Flags::default(),
    contents,
);

let (id, path) = loop {
    match store.resume(arg.take()) {
        MaildirMessageStoreResult::Ok { id, path } => break (id, path),
        MaildirMessageStoreResult::Io(input) => arg = Some(handle(input).unwrap()),
        MaildirMessageStoreResult::Err(err) => panic!("{err}"),
    }
};

println!("stored {id} at {}", path.display());

See complete examples at ./examples.

More examples

Have a look at projects built on the top of this library:

License

This project is licensed under either of:

at your option.

Social

Sponsoring

nlnet

Special thanks to the NLnet foundation and the European Commission that have been financially supporting the project for years:

If you appreciate the project, feel free to donate using one of the following providers:

GitHub Ko-fi Buy Me a Coffee Liberapay thanks.dev PayPal

About

Set of I/O-free coroutines to manage Maildir filesystems

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Contributing

Security policy

Stars

Watchers

Forks

Contributors