asana_cli/models/
section.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Ord, PartialOrd)]
7#[serde(rename_all = "snake_case")]
8pub struct SectionReference {
9 pub gid: String,
11 #[serde(default)]
13 pub name: Option<String>,
14 #[serde(default)]
16 pub resource_type: Option<String>,
17}
18
19impl SectionReference {
20 #[must_use]
22 pub fn label(&self) -> String {
23 self.name.clone().unwrap_or_else(|| self.gid.clone())
24 }
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
29#[serde(rename_all = "snake_case")]
30pub struct Section {
31 pub gid: String,
33 pub name: String,
35 #[serde(default)]
37 pub resource_type: Option<String>,
38 #[serde(default)]
40 pub created_at: Option<String>,
41 #[serde(default)]
43 pub project: Option<SectionProjectReference>,
44 #[serde(default)]
46 pub projects: Vec<SectionProjectReference>,
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Ord, PartialOrd)]
51#[serde(rename_all = "snake_case")]
52pub struct SectionProjectReference {
53 pub gid: String,
55 #[serde(default)]
57 pub name: Option<String>,
58 #[serde(default)]
60 pub resource_type: Option<String>,
61}
62
63impl SectionProjectReference {
64 #[must_use]
66 pub fn label(&self) -> String {
67 self.name.clone().unwrap_or_else(|| self.gid.clone())
68 }
69}
70
71#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
73#[serde(rename_all = "snake_case")]
74pub struct SectionCreateData {
75 pub name: String,
77 #[serde(skip_serializing_if = "Option::is_none")]
79 pub insert_before: Option<String>,
80 #[serde(skip_serializing_if = "Option::is_none")]
82 pub insert_after: Option<String>,
83}
84
85#[derive(Debug, Clone, Serialize)]
87pub struct SectionCreateRequest {
88 pub data: SectionCreateData,
90}
91
92#[derive(Debug, Clone, Default, Serialize, PartialEq, Eq)]
94#[serde(rename_all = "snake_case")]
95pub struct SectionUpdateData {
96 #[serde(skip_serializing_if = "Option::is_none")]
98 pub name: Option<String>,
99}
100
101#[derive(Debug, Clone, Serialize)]
103pub struct SectionUpdateRequest {
104 pub data: SectionUpdateData,
106}
107
108#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
110#[serde(rename_all = "snake_case")]
111pub struct AddTaskToSectionData {
112 pub task: String,
114 #[serde(skip_serializing_if = "Option::is_none")]
116 pub insert_before: Option<String>,
117 #[serde(skip_serializing_if = "Option::is_none")]
119 pub insert_after: Option<String>,
120}
121
122#[derive(Debug, Clone, Serialize)]
124pub struct AddTaskToSectionRequest {
125 pub data: AddTaskToSectionData,
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132
133 #[test]
134 fn section_reference_label_uses_name() {
135 let section = SectionReference {
136 gid: "123".to_string(),
137 name: Some("In Progress".to_string()),
138 resource_type: Some("section".to_string()),
139 };
140 assert_eq!(section.label(), "In Progress");
141 }
142
143 #[test]
144 fn section_reference_label_fallback_to_gid() {
145 let section = SectionReference {
146 gid: "456".to_string(),
147 name: None,
148 resource_type: Some("section".to_string()),
149 };
150 assert_eq!(section.label(), "456");
151 }
152
153 #[test]
154 fn create_request_serializes_correctly() {
155 let request = SectionCreateRequest {
156 data: SectionCreateData {
157 name: "New Section".to_string(),
158 insert_before: None,
159 insert_after: Some("789".to_string()),
160 },
161 };
162 let json = serde_json::to_string(&request).unwrap();
163 assert!(json.contains("\"name\":\"New Section\""));
164 assert!(json.contains("\"insert_after\":\"789\""));
165 assert!(!json.contains("insert_before"));
166 }
167
168 #[test]
169 fn add_task_request_serializes_correctly() {
170 let request = AddTaskToSectionRequest {
171 data: AddTaskToSectionData {
172 task: "task123".to_string(),
173 insert_before: Some("task456".to_string()),
174 insert_after: None,
175 },
176 };
177 let json = serde_json::to_string(&request).unwrap();
178 assert!(json.contains("\"task\":\"task123\""));
179 assert!(json.contains("\"insert_before\":\"task456\""));
180 assert!(!json.contains("insert_after"));
181 }
182}