use crate::api::tree::Treeable;
use owo_colors::{OwoColorize, Stream};
use reqwest::Url;
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
pub type ProjectID = String;
pub type ProjectSyncID = String;
#[serde_as]
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Clone)]
pub struct Project {
pub id: ProjectID,
pub parent_id: Option<ProjectID>,
pub name: String,
pub color: String,
pub is_shared: bool,
pub child_order: isize,
pub inbox_project: bool,
pub is_favorite: bool,
pub url: Option<Url>,
#[serde(default)]
pub view_style: ViewStyle,
}
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Clone)]
#[serde(rename_all = "lowercase")]
#[derive(Default)]
pub enum ViewStyle {
#[default]
List,
Board,
Calendar,
}
impl Treeable for Project {
type ID = ProjectID;
fn id(&self) -> ProjectID {
self.id.clone()
}
fn parent_id(&self) -> Option<ProjectID> {
self.parent_id.clone()
}
fn reset_parent(&mut self) {
self.parent_id = None;
}
}
impl std::fmt::Display for Project {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{} {}",
self.id
.if_supports_color(Stream::Stdout, |text| text.bright_yellow()),
self.name
)
}
}
#[derive(Debug, Serialize, Deserialize, Default)]
pub struct CreateProject {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub parent_id: Option<ProjectID>,
#[serde(skip_serializing_if = "Option::is_none")]
pub color: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub favorite: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub view_style: Option<ViewStyle>,
}
#[cfg(test)]
impl Project {
pub fn new(id: &str, name: &str) -> Project {
Project {
id: id.to_string(),
name: name.to_string(),
parent_id: None,
color: "".to_string(),
is_shared: false,
child_order: 0,
inbox_project: false,
is_favorite: false,
url: Some("http://localhost".to_string().parse().unwrap()),
view_style: Default::default(),
}
}
}