perspective_client/config/
sort.rs1use std::fmt::Display;
14
15use serde::{Deserialize, Serialize};
16use ts_rs::TS;
17
18use crate::proto;
19
20#[derive(Clone, Deserialize, Debug, Eq, PartialEq, Serialize, TS)]
21#[serde()]
22pub struct Sort(pub String, pub SortDir);
23
24#[derive(Clone, Copy, Deserialize, Debug, Eq, PartialEq, Serialize, TS)]
25#[serde()]
26pub enum SortDir {
27 #[serde(rename = "none")]
28 None,
29
30 #[serde(rename = "desc")]
31 Desc,
32
33 #[serde(rename = "asc")]
34 Asc,
35
36 #[serde(rename = "col desc")]
37 ColDesc,
38
39 #[serde(rename = "col asc")]
40 ColAsc,
41
42 #[serde(rename = "desc abs")]
43 DescAbs,
44
45 #[serde(rename = "asc abs")]
46 AscAbs,
47
48 #[serde(rename = "col desc abs")]
49 ColDescAbs,
50
51 #[serde(rename = "col asc abs")]
52 ColAscAbs,
53}
54
55impl Display for SortDir {
56 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
57 write!(fmt, "{}", match self {
58 Self::None => "none",
59 Self::Desc => "desc",
60 Self::Asc => "asc",
61 Self::ColDesc => "col desc",
62 Self::ColAsc => "col asc",
63 Self::DescAbs => "desc abs",
64 Self::AscAbs => "asc abs",
65 Self::ColDescAbs => "col desc abs",
66 Self::ColAscAbs => "col asc abs",
67 })
68 }
69}
70
71impl SortDir {
72 pub fn cycle(&self, split_by: bool, abs: bool) -> Self {
74 let order: &[Self] = match (split_by, abs) {
75 (false, false) => &[Self::None, Self::Asc, Self::Desc],
76 (false, true) => &[Self::None, Self::AscAbs, Self::DescAbs],
77 (true, false) => &[
78 Self::None,
79 Self::Asc,
80 Self::Desc,
81 Self::ColAsc,
82 Self::ColDesc,
83 ],
84 (true, true) => &[
85 Self::None,
86 Self::AscAbs,
87 Self::DescAbs,
88 Self::ColAscAbs,
89 Self::ColDescAbs,
90 ],
91 };
92
93 let index = order.iter().position(|x| x == self).unwrap_or(0);
94 order[(index + 1) % order.len()]
95 }
96}
97
98impl From<SortDir> for proto::SortOp {
99 fn from(value: SortDir) -> Self {
100 match value {
101 SortDir::None => proto::SortOp::SortNone,
102 SortDir::Desc => proto::SortOp::SortDesc,
103 SortDir::Asc => proto::SortOp::SortAsc,
104 SortDir::ColDesc => proto::SortOp::SortColDesc,
105 SortDir::ColAsc => proto::SortOp::SortColAsc,
106 SortDir::DescAbs => proto::SortOp::SortDescAbs,
107 SortDir::AscAbs => proto::SortOp::SortAscAbs,
108 SortDir::ColDescAbs => proto::SortOp::SortColDescAbs,
109 SortDir::ColAscAbs => proto::SortOp::SortColAscAbs,
110 }
111 }
112}
113
114impl From<proto::SortOp> for SortDir {
115 fn from(value: proto::SortOp) -> Self {
116 match value {
117 proto::SortOp::SortNone => SortDir::None,
118 proto::SortOp::SortDesc => SortDir::Desc,
119 proto::SortOp::SortAsc => SortDir::Asc,
120 proto::SortOp::SortColAsc => SortDir::ColAsc,
121 proto::SortOp::SortColDesc => SortDir::ColDesc,
122 proto::SortOp::SortAscAbs => SortDir::AscAbs,
123 proto::SortOp::SortDescAbs => SortDir::DescAbs,
124 proto::SortOp::SortColAscAbs => SortDir::ColAscAbs,
125 proto::SortOp::SortColDescAbs => SortDir::ColDescAbs,
126 }
127 }
128}
129
130impl From<Sort> for proto::view_config::Sort {
131 fn from(value: Sort) -> Self {
132 proto::view_config::Sort {
133 column: value.0,
134 op: proto::SortOp::from(value.1).into(),
135 }
136 }
137}
138
139impl From<proto::view_config::Sort> for Sort {
140 fn from(value: proto::view_config::Sort) -> Self {
141 Sort(
142 value.column,
143 proto::SortOp::try_from(value.op).unwrap().into(),
144 )
145 }
146}