use anyhow::{anyhow, Error};
use clap::ValueEnum;
use serde::{Deserialize, Serialize};
use std::{fmt::Display, str::FromStr};
use tui::{style::Modifier, widgets::BorderType};
macro_rules! impl_display {
($enum_name:ident) => {
impl std::fmt::Display for $enum_name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&super::parsers::enum_debug_display_parser(&format!(
"{:?}",
self
)))?;
Ok(())
}
}
};
}
#[derive(Default, Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize, ValueEnum)]
pub enum PasteBehavior {
AsKeys,
#[default]
Insert,
None,
}
impl_display!(PasteBehavior);
#[derive(Serialize, Deserialize, ValueEnum, Clone, Debug, PartialEq, Eq, Default)]
pub enum SetFinalDateType {
Override,
#[default]
OnlyMissing,
Never,
}
impl_display!(SetFinalDateType);
#[derive(Clone, Copy, Serialize, Deserialize, ValueEnum, Debug, PartialEq, Eq)]
pub enum TaskSort {
Reverse,
Priority,
Alphanumeric,
AlphanumericReverse,
CreateDateAsc,
CreateDateDesc,
FinishDateAsc,
FinishDateDesc,
DueDateAsc,
DueDateDesc,
}
impl_display!(TaskSort);
#[derive(Clone, Copy, Serialize, Deserialize, Default, ValueEnum, Debug, PartialEq, Eq)]
pub enum SavePolicy {
ManualOnly,
AutoSave,
#[default]
OnChange,
}
impl_display!(SavePolicy);
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq)]
pub enum TextModifier {
Bold,
Italic,
Underlined,
}
impl FromStr for TextModifier {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"bold" => Ok(Self::Bold),
"italic" => Ok(Self::Italic),
"underline" => Ok(Self::Underlined),
_ => Err(anyhow!("Modifier '{s}' is invalid.")),
}
}
}
impl From<TextModifier> for Modifier {
fn from(val: TextModifier) -> Self {
use TextModifier::*;
match val {
Bold => Modifier::BOLD,
Italic => Modifier::ITALIC,
Underlined => Modifier::UNDERLINED,
}
}
}
#[derive(Serialize, Deserialize, ValueEnum, Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum WidgetBorderType {
Plain,
#[default]
Rounded,
Double,
Thick,
}
impl Display for WidgetBorderType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&super::parsers::enum_debug_display_parser(&format!(
"{:?}",
self
)))?;
Ok(())
}
}
impl From<WidgetBorderType> for BorderType {
fn from(value: WidgetBorderType) -> Self {
match value {
WidgetBorderType::Plain => Self::Plain,
WidgetBorderType::Rounded => Self::Rounded,
WidgetBorderType::Double => Self::Double,
WidgetBorderType::Thick => Self::Thick,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use anyhow::Result;
#[test]
fn set_final_date_type_display() {
assert_eq!(format!("{}", SetFinalDateType::Override), "override");
assert_eq!(format!("{}", SetFinalDateType::OnlyMissing), "only-missing");
assert_eq!(format!("{}", SetFinalDateType::Never), "never");
}
#[test]
fn task_sort_display() {
assert_eq!(format!("{}", TaskSort::Reverse), "reverse");
assert_eq!(format!("{}", TaskSort::Priority), "priority");
assert_eq!(format!("{}", TaskSort::Alphanumeric), "alphanumeric");
assert_eq!(
format!("{}", TaskSort::AlphanumericReverse),
"alphanumeric-reverse"
);
assert_eq!(format!("{}", TaskSort::CreateDateAsc), "create-date-asc");
assert_eq!(format!("{}", TaskSort::CreateDateDesc), "create-date-desc");
assert_eq!(format!("{}", TaskSort::FinishDateAsc), "finish-date-asc");
assert_eq!(format!("{}", TaskSort::FinishDateDesc), "finish-date-desc");
assert_eq!(format!("{}", TaskSort::DueDateAsc), "due-date-asc");
assert_eq!(format!("{}", TaskSort::DueDateDesc), "due-date-desc");
}
#[test]
fn fom_str_text_modifier() -> Result<()> {
assert_eq!(TextModifier::from_str("bold")?, TextModifier::Bold);
assert_eq!(TextModifier::from_str("iTALic")?, TextModifier::Italic);
assert!(TextModifier::from_str("Some random data").is_err());
Ok(())
}
#[test]
fn to_text_modifier() {
let bold = TextModifier::Bold;
assert_eq!(Modifier::from(bold), Modifier::BOLD);
let italic = TextModifier::Italic;
assert_eq!(Modifier::from(italic), Modifier::ITALIC);
let underline = TextModifier::Underlined;
assert_eq!(Modifier::from(underline), Modifier::UNDERLINED);
}
#[test]
fn widget_border_type_display() {
assert_eq!(format!("{}", WidgetBorderType::Plain), "plain");
assert_eq!(format!("{}", WidgetBorderType::Rounded), "rounded");
assert_eq!(format!("{}", WidgetBorderType::Double), "double");
assert_eq!(format!("{}", WidgetBorderType::Thick), "thick");
}
#[test]
fn widget_border_type_into_border_type() {
assert_eq!(BorderType::from(WidgetBorderType::Plain), BorderType::Plain);
assert_eq!(
BorderType::from(WidgetBorderType::Rounded),
BorderType::Rounded
);
assert_eq!(
BorderType::from(WidgetBorderType::Double),
BorderType::Double
);
assert_eq!(BorderType::from(WidgetBorderType::Thick), BorderType::Thick);
}
}