use pest_consume::Parser;
use crate::sql::expression::parser::{ExpressionParser, Result, Rule};
use crate::sql::expression::value::*;
use crate::todo::Todo;
#[derive(Eq, PartialEq, Hash, Debug)]
pub enum TodoField {
FullText,
IsCompleted,
Id,
IsBlockingFor,
IsBlocked,
BlockedBy,
CreationDate,
CompletionDate,
Priority,
CanonicalContext,
Contexts,
CanonicalProject,
Projects,
DueDate,
ThresholdDate,
IsHidden,
}
impl TodoField {
fn map_or_null<T, F: FnOnce(T) -> Value>(o: Option<T>, f: F) -> Value {
match o {
Some(t) => f(t),
None => Value::Null,
}
}
pub fn get_value(&self, t: &Todo) -> Value {
let val = match self {
TodoField::FullText => Value::Text(format!("{}", t)),
TodoField::IsCompleted => Value::Boolean(t.is_completed),
TodoField::Id => unimplemented!(),
TodoField::IsBlockingFor => unimplemented!(),
TodoField::IsBlocked => unimplemented!(),
TodoField::BlockedBy => unimplemented!(),
TodoField::CreationDate => TodoField::map_or_null(t.creation_date, Value::Date),
TodoField::CompletionDate => TodoField::map_or_null(t.completion_date, Value::Date),
TodoField::Priority => {
TodoField::map_or_null(t.priority, |pri| Value::Text(pri.to_string()))
}
TodoField::CanonicalContext => {
TodoField::map_or_null(t.canonical_context(), Value::Text)
}
TodoField::CanonicalProject => {
TodoField::map_or_null(t.canonical_project(), Value::Text)
}
TodoField::Contexts => Value::Set(t.contexts.iter().map(|s| s.to_string()).collect()),
TodoField::Projects => Value::Set(t.projects.iter().map(|s| s.to_string()).collect()),
TodoField::DueDate => TodoField::map_or_null(t.due_date, Value::Date),
TodoField::ThresholdDate => TodoField::map_or_null(t.threshold_date, Value::Date),
TodoField::IsHidden => Value::Boolean(t.is_hidden),
};
val
}
pub fn parse(input: &str) -> Result<TodoField> {
let nodes = ExpressionParser::parse(Rule::todo_field, input)?;
let node = nodes.single()?;
let v = ExpressionParser::todo_field(node)?;
Ok(v)
}
}