1use crate::errors::{Error, Result};
2use serde_json::Value;
3use std::cmp::Ordering;
4
5#[derive(PartialEq, Default, Copy, Clone)]
6pub struct OrderedF64(f64);
7
8impl OrderedF64 {
9 fn new(n: f64) -> Self {
10 OrderedF64(n)
11 }
12}
13
14impl Eq for OrderedF64 {}
15
16impl Ord for OrderedF64 {
17 fn cmp(&self, other: &OrderedF64) -> Ordering {
18 self.partial_cmp(other).unwrap()
20 }
21}
22
23impl PartialOrd for OrderedF64 {
24 fn partial_cmp(&self, other: &OrderedF64) -> Option<Ordering> {
25 Some(total_cmp(&self.0, &other.0))
26 }
27}
28
29#[must_use]
63#[inline]
64fn total_cmp(a: &f64, b: &f64) -> Ordering {
65 let mut left = a.to_bits() as i64;
66 let mut right = b.to_bits() as i64;
67 left ^= (((left >> 63) as u64) >> 1) as i64;
68 right ^= (((right >> 63) as u64) >> 1) as i64;
69
70 left.cmp(&right)
71}
72
73#[derive(Default, Eq, PartialEq, Ord, PartialOrd, Copy, Clone)]
74pub struct ArrayLen(usize);
75
76pub trait GetValue: Ord + Sized + Clone {
77 fn get_value(val: &Value) -> Result<Self>;
78}
79
80impl GetValue for OrderedF64 {
81 fn get_value(val: &Value) -> Result<Self> {
82 let n = val.as_f64().ok_or_else(|| Error::msg(format!("expected number got {}", val)))?;
83 Ok(OrderedF64::new(n))
84 }
85}
86
87impl GetValue for i64 {
88 fn get_value(val: &Value) -> Result<Self> {
89 val.as_i64().ok_or_else(|| Error::msg(format!("expected number got {}", val)))
90 }
91}
92
93impl GetValue for bool {
94 fn get_value(val: &Value) -> Result<Self> {
95 val.as_bool().ok_or_else(|| Error::msg(format!("expected bool got {}", val)))
96 }
97}
98
99impl GetValue for String {
100 fn get_value(val: &Value) -> Result<Self> {
101 let str: Result<&str> =
102 val.as_str().ok_or_else(|| Error::msg(format!("expected string got {}", val)));
103 Ok(str?.to_owned())
104 }
105}
106
107impl GetValue for ArrayLen {
108 fn get_value(val: &Value) -> Result<Self> {
109 let arr =
110 val.as_array().ok_or_else(|| Error::msg(format!("expected array got {}", val)))?;
111 Ok(ArrayLen(arr.len()))
112 }
113}
114
115#[derive(Default)]
116pub struct SortPairs<K: Ord> {
117 pairs: Vec<(Value, K)>,
118}
119
120type SortNumbers = SortPairs<OrderedF64>;
121type SortBools = SortPairs<bool>;
122type SortStrings = SortPairs<String>;
123type SortArrays = SortPairs<ArrayLen>;
124
125impl<K: GetValue> SortPairs<K> {
126 fn try_add_pair(&mut self, val: &Value, key: &Value) -> Result<()> {
127 let key = K::get_value(key)?;
128 self.pairs.push((val.clone(), key));
129 Ok(())
130 }
131
132 fn sort(&mut self) -> Vec<Value> {
133 self.pairs.sort_by_key(|a| a.1.clone());
134 self.pairs.iter().map(|a| a.0.clone()).collect()
135 }
136}
137
138pub trait SortStrategy {
139 fn try_add_pair(&mut self, val: &Value, key: &Value) -> Result<()>;
140 fn sort(&mut self) -> Vec<Value>;
141}
142
143impl<K: GetValue> SortStrategy for SortPairs<K> {
144 fn try_add_pair(&mut self, val: &Value, key: &Value) -> Result<()> {
145 SortPairs::try_add_pair(self, val, key)
146 }
147
148 fn sort(&mut self) -> Vec<Value> {
149 SortPairs::sort(self)
150 }
151}
152
153pub fn get_sort_strategy_for_type(ty: &Value) -> Result<Box<dyn SortStrategy>> {
154 use crate::Value::*;
155 match *ty {
156 Null => Err(Error::msg("Null is not a sortable value")),
157 Bool(_) => Ok(Box::<SortBools>::default()),
158 Number(_) => Ok(Box::<SortNumbers>::default()),
159 String(_) => Ok(Box::<SortStrings>::default()),
160 Array(_) => Ok(Box::<SortArrays>::default()),
161 Object(_) => Err(Error::msg("Object is not a sortable value")),
162 }
163}
164
165#[derive(Default)]
166pub struct Unique<K: Eq + std::hash::Hash> {
167 unique: std::collections::HashSet<K>,
168}
169
170type UniqueNumbers = Unique<i64>;
171type UniqueBools = Unique<bool>;
172struct UniqueStrings {
173 u: Unique<String>,
174 case_sensitive: bool,
175}
176
177pub trait UniqueStrategy {
178 fn insert(&mut self, val: &Value) -> Result<bool>;
179}
180
181impl<K: GetValue + Eq + std::hash::Hash> UniqueStrategy for Unique<K> {
182 fn insert(&mut self, val: &Value) -> Result<bool> {
183 Ok(self.unique.insert(K::get_value(val)?))
184 }
185}
186
187impl UniqueStrings {
188 fn new(case_sensitive: bool) -> UniqueStrings {
189 UniqueStrings { u: Unique::<String>::default(), case_sensitive }
190 }
191}
192
193impl UniqueStrategy for UniqueStrings {
194 fn insert(&mut self, val: &Value) -> Result<bool> {
195 let mut key = String::get_value(val)?;
196 if !self.case_sensitive {
197 key = key.to_lowercase()
198 }
199 Ok(self.u.unique.insert(key))
200 }
201}
202
203pub fn get_unique_strategy_for_type(
204 ty: &Value,
205 case_sensitive: bool,
206) -> Result<Box<dyn UniqueStrategy>> {
207 use crate::Value::*;
208 match *ty {
209 Null => Err(Error::msg("Null is not a unique value")),
210 Bool(_) => Ok(Box::<UniqueBools>::default()),
211 Number(ref val) => {
212 if val.is_f64() {
213 Err(Error::msg("Unique floats are not implemented"))
214 } else {
215 Ok(Box::<UniqueNumbers>::default())
216 }
217 }
218 String(_) => Ok(Box::new(UniqueStrings::new(case_sensitive))),
219 Array(_) => Err(Error::msg("Unique arrays are not implemented")),
220 Object(_) => Err(Error::msg("Unique objects are not implemented")),
221 }
222}