api_tools/value_objects/
query_sort.rs1use std::fmt::Display;
4
5pub type QuerySortField = String;
7
8#[derive(Debug, Clone, Default, PartialEq, Eq)]
10pub enum QuerySortDirection {
11 #[default]
14 Asc,
15
16 Desc,
19}
20
21impl Display for QuerySortDirection {
22 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23 write!(
24 f,
25 "{}",
26 match self {
27 Self::Asc => "ASC",
28 Self::Desc => "DESC",
29 }
30 )
31 }
32}
33
34#[derive(Debug, Clone, Default, PartialEq, Eq)]
35pub struct QuerySort {
36 pub field: QuerySortField,
37 pub direction: QuerySortDirection,
38}
39
40impl QuerySort {
41 pub fn new(field: QuerySortField, direction: QuerySortDirection) -> Self {
43 Self { field, direction }
44 }
45}
46
47#[derive(Debug, Clone, Default, PartialEq, Eq)]
49pub struct QuerySorts(pub Vec<QuerySort>);
50
51impl From<&str> for QuerySorts {
52 fn from(value: &str) -> Self {
74 let mut sorts = Vec::new();
75 let parts = value.split(',');
76
77 for part in parts {
78 let prefix = part.chars().next();
79 if let Some(prefix) = prefix {
80 if prefix == '+' {
81 sorts.push(QuerySort::new(part[1..].to_string(), QuerySortDirection::Asc));
82 } else if prefix == '-' {
83 sorts.push(QuerySort::new(part[1..].to_string(), QuerySortDirection::Desc));
84 }
85 }
86 }
87
88 Self(sorts)
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95
96 #[test]
97 fn test_query_sort_direction_default() {
98 assert_eq!(QuerySortDirection::default(), QuerySortDirection::Asc);
99 }
100
101 #[test]
102 fn test_query_sort_direction_display() {
103 assert_eq!("ASC", QuerySortDirection::Asc.to_string());
104 assert_eq!("DESC", QuerySortDirection::Desc.to_string());
105 }
106
107 #[test]
108 fn test_filter_sorts_from_str() {
109 let sorts = QuerySorts::from("");
110 assert!(sorts.0.is_empty());
111
112 let sorts = QuerySorts::from("+id,-name");
113 assert_eq!(sorts.0.len(), 2);
114 assert_eq!(
115 sorts.0,
116 vec![
117 QuerySort {
118 field: "id".to_string(),
119 direction: QuerySortDirection::Asc
120 },
121 QuerySort {
122 field: "name".to_string(),
123 direction: QuerySortDirection::Desc
124 },
125 ]
126 );
127
128 let sorts = QuerySorts::from("id");
129 assert!(sorts.0.is_empty());
130 }
131}