1use crate::objects::*;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4use std::{collections::*, fmt::Display};
5
6pub(crate) trait ChartJsRsObject {
7 fn is_empty(&self) -> bool;
8}
9impl<T: Display> ChartJsRsObject for T {
10 fn is_empty(&self) -> bool {
11 self.to_string().is_empty()
12 }
13}
14
15pub trait DatasetTrait:
16 for<'a> Deserialize<'a> + Serialize + Default + Clone + Send + 'static
17{
18 fn labels(self) -> Vec<NumberOrDateString>;
19}
20pub trait DatasetDataExt {
21 fn presorted_to_dataset_data(self) -> DatasetData;
22 fn unsorted_to_dataset_data(self) -> DatasetData;
23}
24
25impl<I> DatasetDataExt for I
26where
27 I: Iterator<Item = (NumberOrDateString, NumberString, Option<Value>)>,
28{
29 fn presorted_to_dataset_data(self) -> DatasetData {
30 DatasetData(serde_json::to_value(self.map(XYPoint::from).collect::<Vec<_>>()).unwrap())
31 }
32 fn unsorted_to_dataset_data(self) -> DatasetData {
33 DatasetData(serde_json::to_value(self.map(XYPoint::from).collect::<BTreeSet<_>>()).unwrap())
34 }
35}
36
37pub trait DatasetIterExt: Iterator {
38 fn into_data_iter<X, Y>(
39 self,
40 ) -> impl Iterator<Item = (NumberOrDateString, NumberString, Option<Value>)>
41 where
42 Self: Iterator<Item = (X, Y)> + Sized,
43 X: Into<NumberOrDateString>,
44 Y: Into<NumberString>,
45 {
46 self.map(|(x, y)| (x.into(), y.into(), None))
47 }
48 fn into_data_iter_with_nulls<X, Y>(
49 self,
50 ) -> impl Iterator<Item = (NumberOrDateString, NumberString, Option<Value>)>
51 where
52 Self: Iterator<Item = (X, Option<Y>)> + Sized,
53 X: Into<NumberOrDateString>,
54 Y: Into<NumberString>,
55 {
56 self.map(|(x, y)| {
57 (
58 x.into(),
59 match y {
60 Some(y) => y.into(),
61 None => "null".into(),
62 },
63 None,
64 )
65 })
66 }
67 fn into_data_iter_with_description<X, Y, D>(
68 self,
69 ) -> impl Iterator<Item = (NumberOrDateString, NumberString, Option<Value>)>
70 where
71 Self: Iterator<Item = (X, Y, D)> + Sized,
72 X: Into<NumberOrDateString>,
73 Y: Into<NumberString>,
74 D: Serialize,
75 {
76 self.map(|(x, y, d)| (x.into(), y.into(), Some(serde_json::to_value(d).unwrap())))
77 }
78 fn into_data_iter_with_nulls_and_description<X, Y, D>(
79 self,
80 ) -> impl Iterator<Item = (NumberOrDateString, NumberString, Option<Value>)>
81 where
82 Self: Iterator<Item = (X, Option<Y>, D)> + Sized,
83 X: Into<NumberOrDateString>,
84 Y: Into<NumberString>,
85 D: Serialize,
86 {
87 self.map(|(x, y, d)| {
88 (
89 x.into(),
90 match y {
91 Some(y) => y.into(),
92 None => "null".into(),
93 },
94 Some(serde_json::to_value(d).unwrap()),
95 )
96 })
97 }
98}
99impl<T> DatasetIterExt for T where T: Iterator + ?Sized {}