singularity_cli/models/
task_group.rs1use serde::{Deserialize, Serialize};
2
3fn display_opt(o: &Option<String>) -> String {
4 o.as_deref().unwrap_or("-").to_string()
5}
6
7#[derive(Debug, Deserialize)]
8#[serde(rename_all = "camelCase")]
9pub struct TaskGroupListResponse {
10 pub task_groups: Vec<TaskGroup>,
11}
12
13#[derive(Debug, Deserialize)]
14pub struct TaskGroup {
15 pub id: String,
16 pub title: String,
17 pub parent: Option<String>,
18 #[serde(rename = "parentOrder")]
19 pub parent_order: Option<f64>,
20 pub fake: Option<bool>,
21 #[serde(rename = "modificatedDate")]
22 #[allow(dead_code)]
23 pub modificated_date: Option<String>,
24}
25
26impl TaskGroup {
27 pub fn display_detail(&self) -> String {
28 let mut lines = vec![
29 format!("**ID:** {}", self.id),
30 format!("**Title:** {}", self.title),
31 ];
32 if let Some(ref v) = self.parent {
33 lines.push(format!("**Parent:** {}", v));
34 }
35 if let Some(v) = self.parent_order {
36 lines.push(format!("**Order:** {}", v));
37 }
38 if let Some(v) = self.fake {
39 lines.push(format!("**Fake:** {}", v));
40 }
41 lines.join("\n")
42 }
43
44 pub fn display_list_item(&self) -> String {
45 format!(
46 "- ID: {}\n Group: {}\n Parent: {}",
47 self.id,
48 self.title,
49 display_opt(&self.parent)
50 )
51 }
52}
53
54#[derive(Debug, Serialize)]
55pub struct TaskGroupCreate {
56 pub title: String,
57 pub parent: String,
58 #[serde(skip_serializing_if = "Option::is_none", rename = "parentOrder")]
59 pub parent_order: Option<f64>,
60 #[serde(skip_serializing_if = "Option::is_none")]
61 pub fake: Option<bool>,
62}
63
64#[derive(Debug, Serialize, Default)]
65pub struct TaskGroupUpdate {
66 #[serde(skip_serializing_if = "Option::is_none")]
67 pub title: Option<String>,
68 #[serde(skip_serializing_if = "Option::is_none")]
69 pub parent: Option<String>,
70 #[serde(skip_serializing_if = "Option::is_none", rename = "parentOrder")]
71 pub parent_order: Option<f64>,
72 #[serde(skip_serializing_if = "Option::is_none")]
73 pub fake: Option<bool>,
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn deserialize_task_group_list() {
82 let json = r#"{"taskGroups": [{"id": "Q-1", "title": "Group 1", "parent": "P-1", "parentOrder": 2.0}]}"#;
83 let resp: TaskGroupListResponse = serde_json::from_str(json).unwrap();
84 assert_eq!(resp.task_groups.len(), 1);
85 assert_eq!(resp.task_groups[0].id, "Q-1");
86 assert_eq!(resp.task_groups[0].parent.as_deref(), Some("P-1"));
87 assert_eq!(resp.task_groups[0].parent_order, Some(2.0));
88 }
89
90 #[test]
91 fn deserialize_task_group_minimal() {
92 let json = r#"{"id": "Q-2", "title": "Bare"}"#;
93 let g: TaskGroup = serde_json::from_str(json).unwrap();
94 assert_eq!(g.id, "Q-2");
95 assert!(g.parent.is_none());
96 assert!(g.fake.is_none());
97 }
98
99 #[test]
100 fn serialize_create_camel_case() {
101 let data = TaskGroupCreate {
102 title: "G".to_string(),
103 parent: "P-1".to_string(),
104 parent_order: Some(3.0),
105 fake: None,
106 };
107 let json = serde_json::to_value(&data).unwrap();
108 assert_eq!(json["parentOrder"], 3.0);
109 assert!(json.get("parent_order").is_none());
110 assert!(json.get("fake").is_none());
111 }
112
113 #[test]
114 fn serialize_update_empty() {
115 let data = TaskGroupUpdate::default();
116 let json = serde_json::to_value(&data).unwrap();
117 assert_eq!(json, serde_json::json!({}));
118 }
119}