diff --git a/melib/src/async.rs b/melib/src/async.rs index 42aa5dd7a..26a024a1a 100644 --- a/melib/src/async.rs +++ b/melib/src/async.rs @@ -1,13 +1,28 @@ +/*! + * Primitive Async/Wait implementation. + * + * To create an Async promise, create an AsyncBuilder. Ask for its channel receiver/sender with + * `tx` and `rx` methods to pass them in your worker's closure. Build an `Async` with your + * `JoinHandle`. The thread must communicate with the `Async` object via `AsyncStatus` + * messages. + * + * When `Async` receives `AsyncStatus::Finished` it joins the thread and takes its value which + * can be extracted with `extract`. + */ + use chan; use std::thread; +/// Messages to pass between `Async` owner and its worker thread. #[derive(Debug)] pub enum AsyncStatus { NoUpdate, Finished, + ///The number may hold whatever meaning the user chooses. ProgressReport(usize), } +/// A builder object for `Async` #[derive(Debug)] pub struct AsyncBuilder { tx: chan::Sender, @@ -22,8 +37,6 @@ pub struct Async { rx: chan::Receiver, } - - impl AsyncBuilder { pub fn new() -> Self { let (sender, receiver) = chan::sync(::std::mem::size_of::()); @@ -32,12 +45,15 @@ impl AsyncBuilder { rx: receiver, } } + /// Returns the sender object of the promise's channel. pub fn tx(&mut self) -> chan::Sender { self.tx.clone() } + /// Returns the receiver object of the promise's channel. pub fn rx(&mut self) -> chan::Receiver { self.rx.clone() } + /// Returns an `Async` object that contains a `Thread` join handle that returns a `T` pub fn build(self, worker: thread::JoinHandle) -> Async { Async { worker: Some(worker), @@ -49,9 +65,11 @@ impl AsyncBuilder { } impl Async { + /// Consumes `self` and returns the computed value. Will panic if computation hasn't finished. pub fn extract(self) -> T { self.value.unwrap() } + /// Polls worker thread and returns result. pub fn poll(&mut self) -> Result { if self.value.is_some() { return Ok(AsyncStatus::Finished); diff --git a/melib/src/error.rs b/melib/src/error.rs index 2aaec9e12..c0c9b581f 100644 --- a/melib/src/error.rs +++ b/melib/src/error.rs @@ -18,6 +18,11 @@ * You should have received a copy of the GNU General Public License * along with meli. If not, see . */ + +/*! + * An error object for `melib` + */ + use std::error::Error; use std::fmt; use std::io; diff --git a/melib/src/lib.rs b/melib/src/lib.rs index d953ff456..56d7d740c 100644 --- a/melib/src/lib.rs +++ b/melib/src/lib.rs @@ -21,7 +21,6 @@ pub mod conf; pub mod error; pub mod mailbox; -pub mod utilities; pub mod async; #[macro_use] @@ -45,4 +44,3 @@ pub use mailbox::*; pub use error::{MeliError, Result}; pub use mailbox::backends::{Backends, RefreshEvent, RefreshEventConsumer}; pub use mailbox::email::{Envelope, Flag}; -pub use utilities::*; diff --git a/melib/src/mailbox/accounts.rs b/melib/src/mailbox/accounts.rs index 5f11a8c76..82fb34287 100644 --- a/melib/src/mailbox/accounts.rs +++ b/melib/src/mailbox/accounts.rs @@ -19,6 +19,10 @@ * along with meli. If not, see . */ +/*! + * Account management from user configuration. + */ + use conf::{AccountSettings, Folder}; use mailbox::backends::{Backends, RefreshEventConsumer}; use mailbox::*; diff --git a/melib/src/mailbox/email/mod.rs b/melib/src/mailbox/email/mod.rs index d300a6919..53aba9903 100644 --- a/melib/src/mailbox/email/mod.rs +++ b/melib/src/mailbox/email/mod.rs @@ -19,6 +19,9 @@ * along with meli. If not, see . */ +/*! + * Email parsing, handling, sending etc. + */ pub mod attachments; pub mod parser; diff --git a/melib/src/mailbox/mod.rs b/melib/src/mailbox/mod.rs index 720cbe516..d9d9eb84d 100644 --- a/melib/src/mailbox/mod.rs +++ b/melib/src/mailbox/mod.rs @@ -19,6 +19,12 @@ * along with meli. If not, see . */ +/*! + * Mail related code. + * + * This module handles reading emails from various backends, handling account data etc + */ + pub mod email; pub use self::email::*; /* Mail backends. Currently only maildir is supported */ diff --git a/melib/src/mailbox/thread.rs b/melib/src/mailbox/thread.rs index c94e17f98..8207de19d 100644 --- a/melib/src/mailbox/thread.rs +++ b/melib/src/mailbox/thread.rs @@ -19,6 +19,10 @@ * along with meli. If not, see . */ +/*! + * Threading algorithm + */ + use error::Result; use mailbox::email::*; use mailbox::Mailbox; @@ -262,6 +266,7 @@ pub fn build_threads( for x in &sent_mailbox.collection { let m_id = x.message_id_raw(); + let x_r_id = x.in_reply_to_raw(); if id_table.contains_key(&m_id) || (!x.in_reply_to_raw().is_empty() && id_table.contains_key(&x.in_reply_to_raw())) @@ -280,7 +285,7 @@ pub fn build_threads( } else if !x.in_reply_to_raw().is_empty() && id_table.contains_key(&x.in_reply_to_raw()) { - let p = id_table[&m_id]; + let p = id_table[&x_r_id]; let c = if id_table.contains_key(&m_id) { id_table[&m_id] } else { diff --git a/melib/src/utilities.rs b/melib/src/utilities.rs deleted file mode 100644 index 438014c9d..000000000 --- a/melib/src/utilities.rs +++ /dev/null @@ -1,11 +0,0 @@ - -pub trait ProgressTracker { - fn new(s: String, total_work: usize) -> Self; - - fn add_work(&mut self, n: usize) -> (); - fn set_work(&mut self, n: usize) -> (); - fn work(&mut self, n: usize) -> (); - - fn percentage(&self) -> usize; - fn description(&self) -> &str; -} diff --git a/src/bin.rs b/src/bin.rs index 97552895c..064acfb93 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -33,7 +33,7 @@ extern crate melib; extern crate ui; pub use melib::*; -use ui::*; +pub use ui::*; use std::thread; @@ -206,10 +206,10 @@ fn main() { } } } - if !flag { - state.finish_startup(); - } - + if !flag { + state.finish_startup(); + } + state.render(); } ThreadEvent::UIEvent(e) => { state.rcv_event(UIEvent { id: 0, event_type: e}); diff --git a/ui/src/components/mail/mod.rs b/ui/src/components/mail/mod.rs index 04d785f6b..775c4f7bf 100644 --- a/ui/src/components/mail/mod.rs +++ b/ui/src/components/mail/mod.rs @@ -14,6 +14,7 @@ struct AccountMenuEntry { entries: Vec<(usize, Folder)>, } +/// The account sidebar. #[derive(Debug)] pub struct AccountMenu { accounts: Vec, diff --git a/ui/src/execute/actions.rs b/ui/src/execute/actions.rs index f4ccb55e7..bf556c4db 100644 --- a/ui/src/execute/actions.rs +++ b/ui/src/execute/actions.rs @@ -1,3 +1,7 @@ +/*! + * User actions that need to be handled by the UI + */ + #[derive(Debug)] pub enum MailListingAction { ToggleThreaded, diff --git a/ui/src/lib.rs b/ui/src/lib.rs index 7bd9497d6..9d49f4dbb 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -19,6 +19,10 @@ * along with meli. If not, see . */ +/*! + * This library exports the public types and methods of its modules + */ + extern crate melib; extern crate mime_apps; extern crate notify_rust; diff --git a/ui/src/state.rs b/ui/src/state.rs index bcd9b5afd..2a335ede5 100644 --- a/ui/src/state.rs +++ b/ui/src/state.rs @@ -1,4 +1,5 @@ -/*! +/*! The application's state. + The UI crate has an Entity-Component-System design. The System part, is also the application's state, so they're both merged in the `State` struct. `State` owns all the Entities of the UI, which are currently plain Containers for `Component`s. In the application's main event loop, input is handed to the state in the form of `UIEvent` objects which traverse the entity graph. Components decide to handle each input or not. @@ -158,11 +159,15 @@ impl State { s } + /// If an owned thread returns a `ThreadEvent::ThreadJoin` event to `State` then it must remove + /// the thread from its list and `join` it. pub fn join(&mut self, id: thread::ThreadId) { let handle = self.threads.remove(&id).unwrap(); handle.join().unwrap(); } + /// If startup has finished, inform startup thread that it doesn't need to tick us with startup + /// check reminders and let it die. pub fn finish_startup(&mut self) { // TODO: Encode startup process with the type system if possible if self.startup_thread.is_none() { @@ -173,6 +178,9 @@ impl State { tx.send(true); } } + + /// Switch back to the terminal's main screen (The command line the user sees before opening + /// the application) pub fn to_main_screen(&mut self) { write!( self.stdout(), @@ -199,6 +207,7 @@ impl State { } } impl State { + /// On `SIGWNICH` the `State` redraws itself according to the new terminal size. pub fn update_size(&mut self) { let termsize = termion::terminal_size().ok(); let termcols = termsize.map(|(w, _)| w); @@ -221,6 +230,7 @@ impl State { }); } + /// Force a redraw for all dirty components. pub fn redraw(&mut self) { for i in 0..self.entities.len() { self.draw_entity(i); @@ -231,6 +241,8 @@ impl State { self.draw_area(a); } } + + /// Draw only a specific `area` on the screen. fn draw_area(&mut self, area: Area) { let upper_left = upper_left!(area); let bottom_right = bottom_right!(area); @@ -269,6 +281,8 @@ impl State { } self.flush(); } + + /// Draw the entire screen from scratch. pub fn render(&mut self) { self.update_size(); @@ -306,6 +320,7 @@ impl State { } } + /// The application's main loop sends `UIEvents` to state via this method. pub fn rcv_event(&mut self, event: UIEvent) { match event.event_type { // Command type is handled only by State. @@ -383,6 +398,8 @@ impl State { }); } } + + pub fn try_wait_on_child(&mut self) -> Option { if { match self.child {