Add some documentation
This commit is contained in:
parent
371d6fb356
commit
e980c597f1
6 changed files with 54 additions and 22 deletions
2
Justfile
Normal file
2
Justfile
Normal file
|
@ -0,0 +1,2 @@
|
|||
doc:
|
||||
cargo doc --document-private-items
|
|
@ -1,3 +1,7 @@
|
|||
//! Module for setting up config files and watchers.
|
||||
//!
|
||||
//! One of the primary goals of panorama is to be able to always hot-reload configuration files.
|
||||
|
||||
use std::fs::File;
|
||||
use std::sync::mpsc::{self, Receiver};
|
||||
use std::time::Duration;
|
||||
|
@ -9,14 +13,22 @@ use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher};
|
|||
use tokio::sync::watch;
|
||||
use xdg::BaseDirectories;
|
||||
|
||||
/// Alias for a MailConfig receiver.
|
||||
pub type ConfigWatcher = watch::Receiver<Option<MailConfig>>;
|
||||
|
||||
/// Configuration
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct MailConfig {
|
||||
/// Host of the IMAP server (needs to be hostname for TLS)
|
||||
pub server: String,
|
||||
|
||||
/// Port of the IMAP server
|
||||
pub port: u16,
|
||||
|
||||
/// Username for authenticating to IMAP
|
||||
pub username: String,
|
||||
|
||||
/// Password for authenticating to IMAP
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
|
@ -46,6 +58,10 @@ async fn read_config(path: impl AsRef<Path>) -> Result<MailConfig> {
|
|||
Ok(config)
|
||||
}
|
||||
|
||||
/// The inner loop of the watcher, which is responsible for taking events received by the watcher
|
||||
/// and trying to parse and return the config.
|
||||
///
|
||||
/// This exists so all errors are able to be caught in one go.
|
||||
async fn watcher_loop(
|
||||
fs_events: Receiver<DebouncedEvent>,
|
||||
config_tx: watch::Sender<Option<MailConfig>>,
|
||||
|
@ -67,6 +83,8 @@ async fn watcher_loop(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Start the entire config watcher system, and return a [ConfigWatcher][self::ConfigWatcher],
|
||||
/// which is a cloneable receiver of config update events.
|
||||
pub fn spawn_config_watcher() -> Result<ConfigWatcher> {
|
||||
let (_watcher, config_rx) = start_watcher()?;
|
||||
let (config_tx, config_update) = watch::channel(None);
|
||||
|
|
20
src/lib.rs
Normal file
20
src/lib.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
//! Panorama
|
||||
//! ===
|
||||
|
||||
#![deny(missing_docs)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate anyhow;
|
||||
#[macro_use]
|
||||
extern crate crossterm;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
#[macro_use]
|
||||
extern crate serde;
|
||||
|
||||
pub mod config;
|
||||
pub mod mail;
|
||||
pub mod ui;
|
||||
|
||||
/// A cloneable type that allows sending an exit-"signal" to stop the application.
|
||||
pub type ExitSender = tokio::sync::oneshot::Sender<()>;
|
|
@ -1,3 +1,5 @@
|
|||
//! Mail
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Display;
|
||||
use std::sync::Arc;
|
||||
|
@ -24,8 +26,12 @@ use tokio_util::codec::{Decoder, LinesCodec, LinesCodecError};
|
|||
|
||||
use crate::config::{MailConfig, ConfigWatcher};
|
||||
|
||||
/// Command sent to the mail thread by something else (i.e. UI)
|
||||
pub enum MailCommand {
|
||||
/// Refresh the list
|
||||
Refresh,
|
||||
|
||||
/// Send a raw command
|
||||
Raw(Command),
|
||||
}
|
||||
|
||||
|
|
27
src/main.rs
27
src/main.rs
|
@ -1,16 +1,3 @@
|
|||
#[macro_use]
|
||||
extern crate anyhow;
|
||||
#[macro_use]
|
||||
extern crate crossterm;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
#[macro_use]
|
||||
extern crate serde;
|
||||
|
||||
mod config;
|
||||
mod mail;
|
||||
mod ui;
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::path::PathBuf;
|
||||
|
@ -20,10 +7,7 @@ use futures::future::TryFutureExt;
|
|||
use structopt::StructOpt;
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
use xdg::BaseDirectories;
|
||||
|
||||
use crate::config::{spawn_config_watcher, MailConfig};
|
||||
|
||||
type ExitSender = oneshot::Sender<()>;
|
||||
use panorama::config::{spawn_config_watcher, MailConfig};
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt(author, about)]
|
||||
|
@ -48,7 +32,6 @@ async fn main() -> Result<()> {
|
|||
let xdg = BaseDirectories::new()?;
|
||||
let config_update = spawn_config_watcher()?;
|
||||
|
||||
let config = MailConfig::default();
|
||||
// let config: MailConfig = {
|
||||
// let config_path = opt
|
||||
// .config_path
|
||||
|
@ -74,10 +57,6 @@ async fn main() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn report_err(err: anyhow::Error) {
|
||||
error!("error: {:?}", err);
|
||||
}
|
||||
|
||||
fn setup_logger(opt: &Opt) -> Result<()> {
|
||||
let mut fern = fern::Dispatch::new()
|
||||
.format(|out, message, record| {
|
||||
|
@ -98,3 +77,7 @@ fn setup_logger(opt: &Opt) -> Result<()> {
|
|||
fern.apply()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn report_err(err: anyhow::Error) {
|
||||
log::error!("error: {:?}", err);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! UI
|
||||
|
||||
mod table;
|
||||
|
||||
use std::io::Write;
|
||||
|
@ -23,6 +25,7 @@ const FRAME: Duration = Duration::from_millis(20);
|
|||
#[derive(Copy, Clone)]
|
||||
pub struct Rect(u16, u16, u16, u16);
|
||||
|
||||
/// UI entrypoint.
|
||||
pub async fn run_ui(mut w: impl Write, exit: ExitSender) -> Result<()> {
|
||||
execute!(w, cursor::Hide, terminal::EnterAlternateScreen)?;
|
||||
terminal::enable_raw_mode()?;
|
||||
|
|
Loading…
Reference in a new issue