1use std::{collections::BTreeMap, fmt::Display};
2
3use serde::Serialize;
4use serde_json::{json, Map, Value};
5
6#[derive(Serialize, Clone)]
7struct MaxMinCount<T> {
8 count: usize,
9 max: T,
10 min: T,
11}
12impl<T: PartialOrd + Default + Clone> MaxMinCount<T> {
13 fn new() -> Self {
14 Self {
15 count: 0,
16 max: T::default(),
17 min: T::default(),
18 }
19 }
20 fn add(&mut self, new_value: &T) {
21 if self.count == 0 {
22 self.max = new_value.clone();
23 self.min = new_value.clone();
24 } else {
25 if new_value > &self.max {
26 self.max = new_value.clone();
27 }
28 if new_value < &self.min {
29 self.min = new_value.clone();
30 }
31 }
32 self.count += 1;
33 }
34 fn merge(&mut self, other: &Self) {
35 if self.count == 0 {
36 self.max = other.max.clone();
37 self.min = other.min.clone();
38 } else {
39 if other.max > self.max {
40 self.max = other.max.clone();
41 }
42 if other.min < self.min {
43 self.min = other.min.clone();
44 }
45 }
46 self.count += other.count;
47 }
48}
49
50#[derive(Serialize, Clone)]
51struct Count {
52 count: usize,
53}
54impl Count {
55 fn new() -> Self {
56 Self { count: 0 }
57 }
58
59 fn add(&mut self) {
60 self.count += 1;
61 }
62 fn merge(&mut self, other: &Self) {
63 self.count += other.count;
64 }
65}
66
67#[derive(Serialize, Clone)]
68struct JsonStatItem {
69 string: MaxMinCount<usize>,
70 int: MaxMinCount<i64>,
71 float: MaxMinCount<f64>,
72 bool: Count,
73 null: Count,
74 object: Count,
75 array: MaxMinCount<usize>,
76}
77impl JsonStatItem {
78 fn new() -> Self {
79 JsonStatItem {
80 string: MaxMinCount::new(),
81 int: MaxMinCount::new(),
82 float: MaxMinCount::new(),
83 bool: Count::new(),
84 null: Count::new(),
85 object: Count::new(),
86 array: MaxMinCount::new(),
87 }
88 }
89 fn merge(&mut self, other: &Self) {
90 self.string.merge(&other.string);
91 self.int.merge(&other.int);
92 self.float.merge(&other.float);
93 self.bool.merge(&other.bool);
94 self.null.merge(&other.null);
95 self.object.merge(&other.object);
96 self.array.merge(&other.array);
97 }
98 fn stat(&mut self, key: &str, data: &Value) -> Vec<(String, Value)> {
99 let mut ret = Vec::new();
100 match data {
101 Value::String(s) => {
102 self.string.add(&s.len());
103 }
104 Value::Number(n) => {
105 if let Some(num) = n.as_i64() {
106 self.int.add(&num);
107 } else if let Some(num) = n.as_f64() {
108 self.float.add(&num);
109 }
110 }
111 Value::Null => {
112 self.null.add();
113 }
114 Value::Bool(_) => {
115 self.bool.add();
116 }
117 Value::Array(arr) => {
118 self.array.add(&arr.len());
119 let k = format!("{}[]", key);
120 for item in arr {
121 ret.push((k.clone(), item.clone()));
122 }
123 }
124 Value::Object(obj) => {
125 self.object.add();
126 for (k, v) in obj {
127 ret.push((format!("{}.{}", key, k), v.clone()));
128 }
129 }
130 }
131 ret
132 }
133 fn to_json_value(&self) -> Value {
134 let mut ret = Map::new();
135 if self.null.count > 0 {
136 ret.insert("null".to_string(), json!({"count": self.null.count}));
137 }
138 if self.bool.count > 0 {
139 ret.insert("bool".to_string(), json!({"count": self.bool.count}));
140 }
141 if self.int.count > 0 {
142 ret.insert(
143 "int".to_string(),
144 json!({
145 "count": self.int.count,
146 "min": self.int.min,
147 "max": self.int.max,
148 }),
149 );
150 }
151 if self.float.count > 0 {
152 ret.insert(
153 "float".to_string(),
154 json!({
155 "count": self.float.count,
156 "min": self.float.min,
157 "max": self.float.max,
158 }),
159 );
160 }
161 if self.string.count > 0 {
162 ret.insert(
163 "string".to_string(),
164 json!({
165 "count": self.string.count,
166 "min": self.string.min,
167 "max": self.string.max,
168 }),
169 );
170 }
171 if self.array.count > 0 {
172 ret.insert(
173 "array".to_string(),
174 json!({
175 "count": self.array.count,
176 "min": self.array.min,
177 "max": self.array.max,
178 }),
179 );
180 }
181 if self.object.count > 0 {
182 ret.insert("object".to_string(), json!({"count": self.object.count}));
183 }
184 Value::Object(ret)
185 }
186}
187
188impl Display for JsonStatItem {
189 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
190 if self.null.count > 0 {
191 write!(f, "null:{};", self.null.count)?;
192 }
193 if self.bool.count > 0 {
194 write!(f, "bool:{};", self.bool.count)?;
195 }
196 if self.int.count > 0 {
197 write!(
198 f,
199 "int:{}({}~{});",
200 self.int.count, self.int.min, self.int.max
201 )?;
202 }
203 if self.float.count > 0 {
204 write!(
205 f,
206 "float:{}({}~{});",
207 self.float.count, self.float.min, self.float.max
208 )?;
209 }
210 if self.string.count > 0 {
211 write!(
212 f,
213 "string:{}({}~{});",
214 self.string.count, self.string.min, self.string.max
215 )?;
216 }
217 if self.array.count > 0 {
218 write!(
219 f,
220 "array:{}({}~{});",
221 self.array.count, self.array.min, self.array.max
222 )?;
223 }
224 if self.object.count > 0 {
225 write!(f, "object:{}", self.object.count)?;
226 }
227 Ok(())
228 }
229}
230pub struct JsonStat {
231 items: BTreeMap<String, JsonStatItem>,
232 group_key: Option<String>,
233}
234impl JsonStat {
235 pub fn new() -> Self {
236 JsonStat {
237 items: BTreeMap::new(),
238 group_key: None,
239 }
240 }
241 pub fn new_by_group(group_key: &str) -> Self {
242 JsonStat {
243 items: BTreeMap::new(),
244 group_key: Some(group_key.to_string()),
245 }
246 }
247 pub fn stat_str(&mut self, line: &str) -> bool {
248 if let Ok(value) = serde_json::from_str(line) {
249 self.stat_value(&value)
250 } else {
251 false
252 }
253 }
254 fn get_group_key(&self, value: &Value) -> String {
255 if let Some(key) = &self.group_key {
256 let mut val = value;
257 for k in key.split('.') {
258 val = match val.as_object() {
259 Some(v) => match v.get(k) {
260 Some(_v) => _v,
261 None => {
262 return "".to_string();
263 }
264 },
265 None => {
266 return "".to_string();
267 }
268 }
269 }
270 if let Some(r) = val.as_str() {
271 r.to_string()
272 } else {
273 "".to_string()
274 }
275 } else {
276 "".to_string()
277 }
278 }
279 pub fn stat_value(&mut self, value: &Value) -> bool {
280 let mut todo_list = Vec::new();
281 todo_list.push((self.get_group_key(value), value.clone()));
282 while let Some((k, v)) = todo_list.pop() {
283 let (item, list) = self.stat_key_value(&k, &v);
284 if !list.is_empty() {
285 todo_list.extend(list);
286 }
287 if let Some(v) = self.items.get_mut(&k) {
288 v.merge(&item);
289 } else {
290 self.items.insert(k, item);
291 }
292 }
293 true
294 }
295 fn stat_key_value(&self, key: &str, value: &Value) -> (JsonStatItem, Vec<(String, Value)>) {
296 let mut item = JsonStatItem::new();
297 let ret = item.stat(key, value);
298 (item, ret)
299 }
300 pub fn merge(&mut self, other: &Self) {
301 for (k, v) in other.items.iter() {
302 if let Some(v1) = self.items.get_mut(k) {
303 v1.merge(v);
304 } else {
305 self.items.insert(k.clone(), v.clone());
306 }
307 }
308 }
309 pub fn to_json_str(&self, full: bool) -> String {
310 if full {
311 serde_json::to_string(&self.items).unwrap()
312 } else {
313 let mut map = Map::new();
314 for (k, v) in self.items.iter() {
315 map.insert(k.clone(), v.to_json_value());
316 }
317 Value::Object(map).to_string()
318 }
319 }
320}
321impl Display for JsonStat {
322 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
323 for (k, v) in self.items.iter() {
324 writeln!(f, "{} : {}", if k.is_empty() { "." } else { k }, v)?;
325 }
326 Ok(())
327 }
328}
329impl Default for JsonStat {
330 fn default() -> Self {
331 Self::new()
332 }
333}