clockify/api/
project.rs

1use std::fmt;
2use crate::clockify::Config; 
3use crate::api::{
4    EndPoint,
5    task::Task,
6    common::{Rate, Membership},
7}; 
8use crate::error::Error;
9use crate::ui::components::Id;
10use serde::{Serialize, Deserialize};
11
12#[derive(Debug, Clone, Serialize, Deserialize, Default)]
13#[serde(rename_all = "camelCase")]
14pub struct Project {
15    pub id: Option<String>,
16    pub name: String,
17    pub hourly_rate: Option<Rate>,
18    pub client_id: Option<String>, 
19    pub client: Option<String>, 
20    pub workspace_id: Option<String>,
21    pub billable: Option<bool>, 
22    pub memberships: Option<Vec<Membership>>, 
23    pub color: Option<String>, 
24    pub estimate: Option<Estimate>, 
25    pub archived: Option<bool>,
26    pub tasks: Option<Vec<Task>>, 
27    pub note: Option<String>, 
28    pub duration: Option<String>, 
29    pub cost_rate: Option<String>, 
30    pub time_estimate: Option<TimeEstimate>, 
31    pub budget_estimate: Option<String>, 
32    pub custom_fields: Option<Vec<CustomField>>, 
33    pub public: Option<bool>, 
34    pub template: Option<bool>, 
35    pub favorite: Option<bool>
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize, Default)]
39#[serde(rename_all = "camelCase")]
40pub struct Estimate {
41    pub estimate: String, 
42    pub r#type: String
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize, Default)]
46#[serde(rename_all = "camelCase")]
47pub struct TimeEstimate {
48    pub estimate: String, 
49    pub r#type: String, 
50    pub reset_option: Option<String>, 
51    pub active: bool, 
52    pub include_non_billable: bool
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize, Default)]
56#[serde(rename_all = "camelCase")]
57pub struct CustomField {
58    pub custom_field_id: String, 
59    pub name: String, 
60    pub r#type: String, 
61    pub value: String, 
62    pub status: String
63}
64
65impl From<&str> for Project {
66    fn from(s: &str) -> Project {
67        Project { name: s.to_string(), ..Default::default() }
68    }
69}
70
71impl fmt::Display for Project {
72    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
73        write!(f, "{}", self.name)
74    }
75}
76
77impl Id for Project {
78    fn id(&self) -> String {
79        return self.id.as_ref().unwrap().clone(); 
80    }
81}
82
83impl EndPoint for Project {
84    fn endpoint(config: &Config) -> Result<String, Error> {
85        Ok(format!("/workspaces/{}/projects", config.workspace_id.as_ref().ok_or(Error::MissingWorkspace)?.clone()))
86    }
87}