1#[derive(Clone, Copy, Debug, PartialEq, Eq)]
10pub struct FacetCaps {
11 pub scalable: bool,
13 pub copyable: bool,
15 pub pasteable: bool,
17 pub cuttable: bool,
19 pub selectable: bool,
21 pub themeable: bool,
23 pub resizable: bool,
25 pub searchable: bool,
27 pub editable: bool,
30 pub navigable: bool,
34}
35
36impl Default for FacetCaps {
37 fn default() -> Self {
38 Self::NONE
39 }
40}
41
42impl FacetCaps {
43 pub const NONE: Self = Self {
45 scalable: false,
46 copyable: false,
47 pasteable: false,
48 cuttable: false,
49 selectable: false,
50 themeable: false,
51 resizable: false,
52 searchable: false,
53 editable: false,
54 navigable: false,
55 };
56
57 pub const ALL: Self = Self {
59 scalable: true,
60 copyable: true,
61 pasteable: true,
62 cuttable: true,
63 selectable: true,
64 themeable: true,
65 resizable: true,
66 searchable: true,
67 editable: true,
68 navigable: true,
69 };
70
71 pub const fn scalable(mut self) -> Self {
73 self.scalable = true;
74 self
75 }
76 pub const fn copyable(mut self) -> Self {
77 self.copyable = true;
78 self
79 }
80 pub const fn pasteable(mut self) -> Self {
81 self.pasteable = true;
82 self
83 }
84 pub const fn cuttable(mut self) -> Self {
86 self.cuttable = true;
87 self.copyable = true;
88 self
89 }
90 pub const fn selectable(mut self) -> Self {
91 self.selectable = true;
92 self
93 }
94 pub const fn themeable(mut self) -> Self {
95 self.themeable = true;
96 self
97 }
98 pub const fn resizable(mut self) -> Self {
99 self.resizable = true;
100 self
101 }
102 pub const fn searchable(mut self) -> Self {
103 self.searchable = true;
104 self
105 }
106 pub const fn editable(mut self) -> Self {
107 self.editable = true;
108 self
109 }
110 pub const fn navigable(mut self) -> Self {
111 self.navigable = true;
112 self
113 }
114
115 pub fn to_json(self) -> serde_json::Value {
117 serde_json::json!({
118 "scalable": self.scalable, "copyable": self.copyable,
119 "pasteable": self.pasteable, "cuttable": self.cuttable,
120 "selectable": self.selectable, "themeable": self.themeable,
121 "resizable": self.resizable, "searchable": self.searchable,
122 "editable": self.editable, "navigable": self.navigable,
123 })
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130
131 #[test]
132 fn none_is_all_false_and_equals_default() {
133 let n = FacetCaps::NONE;
134 assert!(!n.scalable && !n.copyable && !n.pasteable && !n.cuttable);
135 assert!(!n.selectable && !n.themeable && !n.resizable && !n.searchable);
136 assert!(!n.editable && !n.navigable);
137 assert_eq!(FacetCaps::default(), FacetCaps::NONE);
138 }
139
140 #[test]
141 fn all_is_all_true() {
142 let a = FacetCaps::ALL;
143 assert!(a.scalable && a.copyable && a.pasteable && a.cuttable);
144 assert!(a.selectable && a.themeable && a.resizable && a.searchable);
145 assert!(a.editable && a.navigable);
146 }
147
148 #[test]
149 fn builders_set_exactly_one_flag() {
150 assert_eq!(FacetCaps::NONE.scalable(), FacetCaps { scalable: true, ..FacetCaps::NONE });
151 assert_eq!(FacetCaps::NONE.selectable(), FacetCaps { selectable: true, ..FacetCaps::NONE });
152 assert_eq!(FacetCaps::NONE.searchable(), FacetCaps { searchable: true, ..FacetCaps::NONE });
153 assert_eq!(FacetCaps::NONE.editable(), FacetCaps { editable: true, ..FacetCaps::NONE });
154 }
155
156 #[test]
157 fn cuttable_implies_copyable() {
158 let c = FacetCaps::NONE.cuttable();
159 assert!(c.cuttable && c.copyable, "cut implies copy");
160 }
161
162 #[test]
163 fn builders_chain_in_const_context() {
164 const C: FacetCaps = FacetCaps::NONE.selectable().copyable().searchable().scalable().resizable().editable();
165 assert!(C.selectable && C.copyable && C.searchable && C.scalable && C.resizable && C.editable);
166 assert!(!C.pasteable && !C.cuttable && !C.themeable);
167 }
168
169 #[test]
170 fn to_json_carries_every_flag() {
171 let j = FacetCaps::NONE.scalable().themeable().editable().to_json();
172 assert_eq!(j["scalable"], true);
173 assert_eq!(j["themeable"], true);
174 assert_eq!(j["editable"], true);
175 assert_eq!(j["copyable"], false);
176 assert_eq!(j["navigable"], false);
177 assert_eq!(j.as_object().unwrap().len(), 10);
179 }
180}