rtd 0.3.3

Manage your todo in command line
Documentation
use crate::model::Task;
use crate::prettytable::{format, Table};
use std::io::Write;

use crate::model::SMART_LISTS;
use super::formatter::Formatter;

pub struct Render<'a> {
    pub tasks: &'a Vec<&'a Task>,
    pub list: Option<&'a str>,
}

impl<'a> Render<'a> {
    pub fn render<W: Write>(self: &Self, w: &mut W) -> Result<(), String> {
        match self.list {
            Some(list) => self.render_list(w, list, None),
            None => self.render_lists(w),
        }

        Ok(())
    }

    fn render_lists<W: Write>(self: &Self, w: &mut W) {
        let mut lists: Vec<&str> = self.tasks.iter().map(|task| task.list.as_str()).collect();
        lists.sort();
        lists.dedup();

        for list in lists.iter() {
            self.render_list(w, list, Some(max_title_width(self.tasks)));
        }
    }

    fn render_list<W: Write>(self: &Self, w: &mut W, list: &str, max_width: Option<usize>) {
        let tasks = self
            .tasks
            .iter()
            .filter(|task| task.is_in_list(list))
            .cloned()
            .collect::<Vec<&Task>>();

        if tasks.is_empty() {
            writeln!(w, "No tasks found for {}", list).unwrap();
        } else {
            let is_smart_list = SMART_LISTS.contains(&list.to_lowercase().as_str());
            let width: usize = max_width.unwrap_or(max_title_width(&tasks));

            writeln!(w, "{}", list).unwrap();
            let mut table = Table::new();
            for task in tasks.iter() {
                let formatter = Formatter::new(task.clone());
                table.add_row(row![
                    formatter.task_id(),
                    formatter.done(),
                    formatter.title(Some(width)),
                    formatter.priority(),
                    formatter.due_date(),
                    formatter.task_list(is_smart_list)
                ]);
            }

            let format = format::FormatBuilder::new().padding(1, 1).build();
            table.set_format(format);
            table.printstd();
        }
    }
}

fn max_title_width(tasks: &Vec<&Task>) -> usize {
    *tasks
        .iter()
        .map(|task| task.title.len())
        .max()
        .get_or_insert(0)
}