1use std::fmt::Display;
2
3use serde::{Serialize, Deserialize};
4use super::enums::*;
5
6const ICON_FAVORITE: &str = "★";
7const ICON_SHARED: &str = "⛹";
8const ICON_INBOX: &str = "✉ ";
9
10#[derive(Serialize, Deserialize, Debug, Clone)]
11pub struct Project {
12 pub id: String,
13 pub name: String,
14 pub comment_count: i64,
15 pub parent_id: Option<String>,
16 pub order: i64,
17 pub color: Color,
18 pub is_shared: bool,
19 pub is_favorite: bool,
20 pub is_inbox_project: bool,
21 pub is_team_inbox: bool,
22 pub view_style: ViewStyle,
23 pub url: String,
24}
25
26impl Display for Project {
27 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28 let fav_icon = if self.is_favorite { ICON_FAVORITE } else { "" };
29 let shared_icon = if self.is_shared { ICON_SHARED } else { "" };
30 let inbox_icon = if self.is_inbox_project { ICON_INBOX } else { "" };
31
32 write!(f, "{} [{}] {}{}{}", self.name, self.id, shared_icon, inbox_icon, fav_icon)
33 }
34}
35
36#[derive(Serialize, Deserialize, Debug, Clone)]
37pub struct Task {
38 pub creator_id: String,
39 pub assignee: Option<String>,
40 pub assigner: Option<String>,
41 pub created_at: String,
42 pub comment_count: i64,
43 pub is_completed: bool,
44 pub content: String,
45 pub description: String,
46 pub due: Option<Due>,
47 pub id: String,
48 pub labels: Vec<String>,
49 pub order: i64,
50 pub priority: Priority,
51 pub project_id: Option<String>,
52 pub section_id: Option<String>,
53 pub parent_id: Option<String>,
54 pub url: String,
55 pub duraction: Option<Duration>,
56}
57
58#[derive(Serialize, Deserialize, Debug, Clone)]
59pub struct Due {
60 pub date: Option<String>,
61 pub datetime: Option<String>,
62 pub is_recurring: bool,
63 pub string: String,
64 pub timezone: Option<String>,
65}
66
67impl std::fmt::Display for Due {
68 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69 if let Some(value) = &self.datetime {
70 write!(f, "{}", value)
71 } else if let Some(value) = &self.date {
72 write!(f, "{}", value)
73 } else {
74 write!(f, "")
75 }
76 }
77}
78
79#[derive(Serialize, Deserialize, Debug, Clone)]
80pub struct Duration {
81 pub amount: i64,
82 pub unit: DurationUnit,
83}
84
85#[derive(Serialize, Deserialize, Debug, Clone)]
86pub struct Collaborator {
87 pub id: String,
88 pub name: String,
89 pub email: String,
90}
91
92impl Display for Collaborator {
93 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94 write!(f, "{} <{}>", self.name, self.email)
95 }
96}
97
98#[derive(Serialize, Deserialize, Debug, Clone)]
99pub struct Comment {
100 pub id: String,
101 pub content: String,
102 pub posted_at: String,
103 pub project_id: Option<String>,
104 pub task_id: Option<String>,
105 pub attachment: Option<Attachment>,
106}
107
108#[derive(Serialize, Deserialize, Debug, Clone)]
109pub struct Attachment {
110 pub file_name: String,
111 pub file_type: String,
112 pub file_url: String,
113 pub resource_type: String,
114}
115
116impl Display for Comment {
117 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118 let content = &self.content;
119 let posted_at = &self.posted_at;
120 let id = &self.id;
121 let parent = if let Some(task_id) = &self.task_id {
122 Some(task_id)
123 } else if let Some(project_id) = &self.project_id {
124 Some(project_id)
125 } else {
126 None
127 };
128
129 if let Some(parent_id) = parent {
130 write!(f, "ID: {}\nParent: {}\n{}\n<{}>", id, parent_id, content, posted_at)
131 } else {
132 write!(f, "ID: {}\n{}\n<{}>", id, content, posted_at)
133 }
134 }
135}
136
137#[derive(Serialize, Deserialize, Debug, Clone)]
138pub struct Section {
139 pub id: String,
140 pub project_id: String,
141 pub name: String,
142 pub order: i64,
143}
144
145impl Display for Section {
146 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
147 write!(f, "[{}] <project:{}> {}", self.id, self.project_id, self.name)
148 }
149}
150
151#[derive(Serialize, Deserialize, Debug, Clone)]
152pub struct Label {
153 pub id: String,
154 pub name: String,
155 pub color: Color,
156 pub order: i64,
157 pub is_favorite: bool,
158}