tudor-sql 0.2.0

Does sql stuff to todo.txt files
Documentation
use std::collections::BTreeSet;

use crate::todo::body_token::TodoBodyToken;
use crate::todo::Todo;

#[derive(Debug)]
pub struct TodoBuilder {
    pub is_completed: bool,
    priority: Option<char>,
    creation_date: Option<time::Date>,
    completion_date: Option<time::Date>,
    tokens: Vec<TodoBodyToken>,
    threshold_date: Option<time::Date>,
    due_date: Option<time::Date>,
    // TODO: make it a BTreeSet<&str>
    contexts: BTreeSet<String>,
    // TODO: make it a BTreeSet<&str>
    projects: BTreeSet<String>,
    is_hidden: bool,
}

impl TodoBuilder {
    pub fn default() -> Self {
        TodoBuilder {
            is_completed: false,
            priority: None,
            creation_date: None,
            completion_date: None,
            tokens: Vec::new(),
            threshold_date: None,
            due_date: None,
            contexts: BTreeSet::new(),
            projects: BTreeSet::new(),
            is_hidden: false,
        }
    }
    pub fn completed(&mut self, completed: bool) -> &mut Self {
        self.is_completed = completed;
        self
    }

    pub fn priority(&mut self, priority: char) -> &mut Self {
        // TODO: return Result<>, check prio char
        self.priority = Some(priority);
        self
    }

    pub fn creation_date(&mut self, creation_date: time::Date) -> &mut Self {
        self.creation_date = Some(creation_date);
        self
    }

    pub fn completion_date(&mut self, completion_date: time::Date) -> &mut Self {
        self.is_completed = true;
        self.completion_date = Some(completion_date);
        self
    }

    #[allow(dead_code)]
    pub fn tokens(&mut self, tokens: Vec<TodoBodyToken>) -> &mut Self {
        for t in tokens {
            self.push_token(t);
        }
        self
    }

    pub fn push_token(&mut self, tkn: TodoBodyToken) {
        self.tokens.push(tkn.clone());
        match tkn {
            TodoBodyToken::Context(s) => {
                self.contexts.insert(s); // TODO: store a reference instead
            }
            TodoBodyToken::Project(s) => {
                self.projects.insert(s); // TODO: store a reference instead
            }
            TodoBodyToken::ThresholdDate(td) => {
                self.threshold_date = Some(td); // TODO: store a reference instead
            }
            TodoBodyToken::DueDate(d) => {
                self.due_date = Some(d); // TODO: store a reference instead
            }
            TodoBodyToken::Hidden(b) => {
                self.is_hidden = b;
            }
            TodoBodyToken::Word(_) => {}
        }
    }

    pub fn build(&mut self) -> Todo {
        let tokens = std::mem::replace(&mut self.tokens, vec![]);
        let contexts = std::mem::replace(&mut self.contexts, BTreeSet::new());
        let projects = std::mem::replace(&mut self.projects, BTreeSet::new());
        Todo {
            is_completed: self.is_completed,
            priority: self.priority,
            creation_date: self.creation_date,
            completion_date: self.completion_date,
            body_tokens: tokens,
            threshold_date: self.threshold_date,
            due_date: self.due_date,
            contexts,
            projects,
            is_hidden: self.is_hidden,
        }
    }
}

#[cfg(test)] // not needed elsewhere for now
#[derive(Debug)]
pub struct TodoBodyTokensBuilder {
    tokens: Vec<TodoBodyToken>,
}

#[cfg(test)]
impl TodoBodyTokensBuilder {
    pub fn default() -> TodoBodyTokensBuilder {
        TodoBodyTokensBuilder { tokens: Vec::new() }
    }
    pub fn word(mut self, s: &str) -> TodoBodyTokensBuilder {
        self.tokens.push(TodoBodyToken::Word(s.to_string()));
        self
    }
    pub fn project(mut self, s: &str) -> TodoBodyTokensBuilder {
        self.tokens.push(TodoBodyToken::Project(s.to_string()));
        self
    }
    pub fn context(mut self, s: &str) -> TodoBodyTokensBuilder {
        self.tokens.push(TodoBodyToken::Context(s.to_string()));
        self
    }
    pub fn threshold_date(mut self, d: time::Date) -> TodoBodyTokensBuilder {
        self.tokens.push(TodoBodyToken::ThresholdDate(d));
        self
    }
    pub fn due_date(mut self, d: time::Date) -> TodoBodyTokensBuilder {
        self.tokens.push(TodoBodyToken::DueDate(d));
        self
    }
    pub fn build(self) -> Vec<TodoBodyToken> {
        self.tokens
    }
}