1use crate::api::ApiResponse;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum SortKey {
8 Name,
9 Created,
10 NumMembers,
11}
12
13impl SortKey {
14 pub fn parse(s: &str) -> Result<Self, String> {
15 match s {
16 "name" => Ok(SortKey::Name),
17 "created" => Ok(SortKey::Created),
18 "num_members" => Ok(SortKey::NumMembers),
19 _ => Err(format!(
20 "Invalid sort key '{}'. Valid values: name, created, num_members",
21 s
22 )),
23 }
24 }
25}
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
29pub enum SortDirection {
30 #[default]
31 Asc,
32 Desc,
33}
34
35impl SortDirection {
36 pub fn parse(s: &str) -> Result<Self, String> {
37 match s {
38 "asc" => Ok(SortDirection::Asc),
39 "desc" => Ok(SortDirection::Desc),
40 _ => Err(format!(
41 "Invalid sort direction '{}'. Valid values: asc, desc",
42 s
43 )),
44 }
45 }
46}
47
48pub fn sort_conversations(response: &mut ApiResponse, key: SortKey, direction: SortDirection) {
50 if let Some(channels) = response.data.get_mut("channels") {
51 if let Some(channels_array) = channels.as_array_mut() {
52 channels_array.sort_by(|a, b| {
53 let ordering = match key {
54 SortKey::Name => {
55 let a_name = a.get("name").and_then(|v| v.as_str()).unwrap_or("");
56 let b_name = b.get("name").and_then(|v| v.as_str()).unwrap_or("");
57 a_name.cmp(b_name)
58 }
59 SortKey::Created => {
60 let a_created = a.get("created").and_then(|v| v.as_i64()).unwrap_or(0);
61 let b_created = b.get("created").and_then(|v| v.as_i64()).unwrap_or(0);
62 a_created.cmp(&b_created)
63 }
64 SortKey::NumMembers => {
65 let a_members = a.get("num_members").and_then(|v| v.as_i64()).unwrap_or(0);
66 let b_members = b.get("num_members").and_then(|v| v.as_i64()).unwrap_or(0);
67 a_members.cmp(&b_members)
68 }
69 };
70
71 match direction {
72 SortDirection::Asc => ordering,
73 SortDirection::Desc => ordering.reverse(),
74 }
75 });
76 }
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83 use serde_json::json;
84 use std::collections::HashMap;
85
86 #[test]
87 fn test_sort_key_parse() {
88 assert_eq!(SortKey::parse("name").unwrap(), SortKey::Name);
89 assert_eq!(SortKey::parse("created").unwrap(), SortKey::Created);
90 assert_eq!(SortKey::parse("num_members").unwrap(), SortKey::NumMembers);
91 assert!(SortKey::parse("invalid").is_err());
92 }
93
94 #[test]
95 fn test_sort_direction_parse() {
96 assert_eq!(SortDirection::parse("asc").unwrap(), SortDirection::Asc);
97 assert_eq!(SortDirection::parse("desc").unwrap(), SortDirection::Desc);
98 assert!(SortDirection::parse("invalid").is_err());
99 }
100
101 #[test]
102 fn test_sort_conversations_by_name() {
103 let mut response = ApiResponse {
104 ok: true,
105 data: HashMap::from([(
106 "channels".to_string(),
107 json!([
108 {"id": "C1", "name": "zebra"},
109 {"id": "C2", "name": "alpha"},
110 {"id": "C3", "name": "beta"},
111 ]),
112 )]),
113 error: None,
114 };
115
116 sort_conversations(&mut response, SortKey::Name, SortDirection::Asc);
117
118 let channels = response.data.get("channels").unwrap().as_array().unwrap();
119 assert_eq!(channels[0].get("name").unwrap().as_str().unwrap(), "alpha");
120 assert_eq!(channels[1].get("name").unwrap().as_str().unwrap(), "beta");
121 assert_eq!(channels[2].get("name").unwrap().as_str().unwrap(), "zebra");
122 }
123
124 #[test]
125 fn test_sort_conversations_by_name_desc() {
126 let mut response = ApiResponse {
127 ok: true,
128 data: HashMap::from([(
129 "channels".to_string(),
130 json!([
131 {"id": "C1", "name": "alpha"},
132 {"id": "C2", "name": "zebra"},
133 {"id": "C3", "name": "beta"},
134 ]),
135 )]),
136 error: None,
137 };
138
139 sort_conversations(&mut response, SortKey::Name, SortDirection::Desc);
140
141 let channels = response.data.get("channels").unwrap().as_array().unwrap();
142 assert_eq!(channels[0].get("name").unwrap().as_str().unwrap(), "zebra");
143 assert_eq!(channels[1].get("name").unwrap().as_str().unwrap(), "beta");
144 assert_eq!(channels[2].get("name").unwrap().as_str().unwrap(), "alpha");
145 }
146
147 #[test]
148 fn test_sort_conversations_by_created() {
149 let mut response = ApiResponse {
150 ok: true,
151 data: HashMap::from([(
152 "channels".to_string(),
153 json!([
154 {"id": "C1", "name": "newest", "created": 300},
155 {"id": "C2", "name": "oldest", "created": 100},
156 {"id": "C3", "name": "middle", "created": 200},
157 ]),
158 )]),
159 error: None,
160 };
161
162 sort_conversations(&mut response, SortKey::Created, SortDirection::Asc);
163
164 let channels = response.data.get("channels").unwrap().as_array().unwrap();
165 assert_eq!(channels[0].get("created").unwrap().as_i64().unwrap(), 100);
166 assert_eq!(channels[1].get("created").unwrap().as_i64().unwrap(), 200);
167 assert_eq!(channels[2].get("created").unwrap().as_i64().unwrap(), 300);
168 }
169
170 #[test]
171 fn test_sort_conversations_by_num_members() {
172 let mut response = ApiResponse {
173 ok: true,
174 data: HashMap::from([(
175 "channels".to_string(),
176 json!([
177 {"id": "C1", "name": "large", "num_members": 100},
178 {"id": "C2", "name": "small", "num_members": 10},
179 {"id": "C3", "name": "medium", "num_members": 50},
180 ]),
181 )]),
182 error: None,
183 };
184
185 sort_conversations(&mut response, SortKey::NumMembers, SortDirection::Asc);
186
187 let channels = response.data.get("channels").unwrap().as_array().unwrap();
188 assert_eq!(
189 channels[0].get("num_members").unwrap().as_i64().unwrap(),
190 10
191 );
192 assert_eq!(
193 channels[1].get("num_members").unwrap().as_i64().unwrap(),
194 50
195 );
196 assert_eq!(
197 channels[2].get("num_members").unwrap().as_i64().unwrap(),
198 100
199 );
200 }
201
202 #[test]
203 fn test_sort_conversations_missing_fields() {
204 let mut response = ApiResponse {
205 ok: true,
206 data: HashMap::from([(
207 "channels".to_string(),
208 json!([
209 {"id": "C1", "name": "has_members", "num_members": 50},
210 {"id": "C2", "name": "no_members"},
211 {"id": "C3", "name": "also_has", "num_members": 10},
212 ]),
213 )]),
214 error: None,
215 };
216
217 sort_conversations(&mut response, SortKey::NumMembers, SortDirection::Asc);
218
219 let channels = response.data.get("channels").unwrap().as_array().unwrap();
220 assert_eq!(
222 channels[0].get("name").unwrap().as_str().unwrap(),
223 "no_members"
224 );
225 assert_eq!(
226 channels[1].get("num_members").unwrap().as_i64().unwrap(),
227 10
228 );
229 assert_eq!(
230 channels[2].get("num_members").unwrap().as_i64().unwrap(),
231 50
232 );
233 }
234}