Skip to main content

chart_js_rs/
traits.rs

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 {}