1use {
2 crate::{traits::*, utils::FnWithArgs},
3 serde::{
4 de::{self, DeserializeOwned},
5 Deserialize, Serialize,
6 },
7 std::fmt::{Debug, Display},
8};
9
10#[derive(Debug, Clone, Deserialize, Serialize, Default, PartialEq, Eq)]
11#[serde(transparent)]
12pub struct DatasetData(pub serde_json::Value);
13impl DatasetData {
14 pub fn is_empty(&self) -> bool {
15 serde_json::to_value(self)
16 .unwrap()
17 .as_array()
18 .unwrap()
19 .is_empty()
20 }
21
22 pub fn from_single_point_array(iter: impl Iterator<Item = [NumberOrDateString; 1]>) -> Self {
23 DatasetData(serde_json::to_value(iter.collect::<Vec<_>>()).unwrap())
24 }
25
26 pub fn from_minmax_array(iter: impl Iterator<Item = [NumberOrDateString; 2]>) -> Self {
27 DatasetData(serde_json::to_value(iter.collect::<Vec<_>>()).unwrap())
28 }
29}
30impl PartialOrd for DatasetData {
31 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
32 Some(self.cmp(other))
33 }
34}
35impl Ord for DatasetData {
36 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
37 self.0.to_string().cmp(&other.0.to_string())
38 }
39}
40
41#[derive(Debug, Clone, Deserialize, Serialize, Default)]
42pub struct NoDatasets {}
43impl DatasetTrait for NoDatasets {
44 fn labels(self) -> Vec<NumberOrDateString> {
45 Vec::new()
46 }
47}
48#[derive(Debug, Deserialize, Serialize, Default)]
49pub struct NoAnnotations {}
50impl Annotation for NoAnnotations {}
51
52#[derive(Debug, Clone, Deserialize, Serialize, Default, PartialEq, Eq, PartialOrd, Ord)]
53pub struct Dataset<D: DatasetTrait> {
54 datasets: D,
55 labels: Option<Vec<NumberOrDateString>>,
56}
57impl<D: DatasetTrait> Dataset<D> {
58 pub fn new() -> Self {
59 Self {
60 datasets: D::default(),
61 labels: None,
62 }
63 }
64 pub fn get_datasets(&mut self) -> &mut D {
65 &mut self.datasets
66 }
67 pub fn datasets(mut self, datasets: impl Into<D>) -> Self {
68 self.datasets = datasets.into();
69 let labels = self.datasets.clone();
70 self.labels(labels.labels())
71 }
72 pub fn get_labels(&mut self) -> &mut Option<Vec<NumberOrDateString>> {
73 &mut self.labels
74 }
75 pub fn labels<T: Into<NumberOrDateString>>(
76 mut self,
77 labels: impl IntoIterator<Item = T>,
78 ) -> Self {
79 self.labels = Some(labels.into_iter().map(Into::into).collect());
80 self
81 }
82}
83#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
84#[serde(untagged)]
85pub enum Any {
86 String(String),
87 Int(isize),
88 Bool(bool),
89 Vec(Vec<()>),
90}
91impl From<bool> for Any {
92 fn from(value: bool) -> Self {
93 Self::Bool(value)
94 }
95}
96impl From<String> for Any {
97 fn from(value: String) -> Self {
98 Self::String(value)
99 }
100}
101impl Any {
102 pub fn is_empty(&self) -> bool {
103 match self {
104 Any::String(s) => s.is_empty(),
105 Any::Int(_i) => false,
106 Any::Bool(_b) => false,
107 Any::Vec(v) => v.is_empty(),
108 }
109 }
110}
111impl Display for Any {
112 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113 match self {
114 Any::String(s) => write!(f, "{s}"),
115 Any::Bool(b) => write!(f, "{b}"),
116 Any::Int(i) => write!(f, "{i}"),
117 Any::Vec(_) => write!(f, ""),
118 }
119 }
120}
121#[derive(Debug, Clone, Default, PartialEq, Eq)]
122pub struct NumberOrDateString(String);
123impl From<NumberString> for NumberOrDateString {
124 fn from(value: NumberString) -> Self {
125 value.0.into()
126 }
127}
128impl NumberOrDateString {
129 pub fn is_empty(&self) -> bool {
130 self.0.is_empty()
131 }
132}
133impl PartialOrd for NumberOrDateString {
134 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
135 Some(self.cmp(other))
136 }
137}
138impl Ord for NumberOrDateString {
139 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
140 if let Some((s, o)) = self
141 .0
142 .parse::<rust_decimal::Decimal>()
143 .ok()
144 .zip(other.0.parse::<rust_decimal::Decimal>().ok())
145 {
146 s.cmp(&o)
147 } else {
148 self.0.cmp(&other.0)
149 }
150 }
151}
152impl<T: Display> From<T> for NumberOrDateString {
153 fn from(s: T) -> Self {
154 Self(s.to_string())
155 }
156}
157#[allow(unknown_lints, clippy::to_string_trait_impl)]
158impl ToString for NumberOrDateString {
159 fn to_string(&self) -> String {
160 self.0.to_string()
161 }
162}
163impl Serialize for NumberOrDateString {
164 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
165 where
166 S: serde::Serializer,
167 {
168 let fnum: Result<f64, _> = self.0.parse();
169 let inum: Result<i64, _> = self.0.parse();
170 match (fnum, inum) {
171 (Ok(_), Ok(inum)) => serializer.serialize_i64(inum),
172 (Ok(fnum), _) => serializer.serialize_f64(fnum),
173 _ => serializer.serialize_str(&self.0),
174 }
175 }
176}
177impl<'de> Deserialize<'de> for NumberOrDateString {
178 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
179 where
180 D: serde::Deserializer<'de>,
181 {
182 Any::deserialize(deserializer).map(|soi| Self(soi.to_string()))
183 }
184}
185
186#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
187pub struct BoolString(String);
188impl BoolString {
189 pub fn opt_true() -> Option<BoolString> {
190 BoolString("true".into()).into()
191 }
192 pub fn opt_false() -> Option<BoolString> {
193 BoolString("false".into()).into()
194 }
195 pub fn _true() -> BoolString {
196 BoolString("true".into())
197 }
198 pub fn _false() -> BoolString {
199 BoolString("false".into())
200 }
201 pub fn is_empty(&self) -> bool {
202 self.0.is_empty()
203 }
204}
205impl<T: Display> From<T> for BoolString {
206 fn from(s: T) -> Self {
207 Self(s.to_string())
208 }
209}
210impl Serialize for BoolString {
211 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
212 where
213 S: serde::Serializer,
214 {
215 let bool_: Result<bool, _> = self.0.parse();
216 let any: Result<String, _> = self.0.parse();
217 match (bool_, any) {
218 (Ok(bool_), _) => serializer.serialize_bool(bool_),
219 (_, Ok(any)) => serializer.serialize_str(&any),
220 _ => unreachable!(),
221 }
222 }
223}
224impl<'de> Deserialize<'de> for BoolString {
225 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
226 where
227 D: serde::Deserializer<'de>,
228 {
229 Any::deserialize(deserializer).map(|soi| Self(soi.to_string()))
230 }
231}
232
233#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
234#[serde(untagged)]
235pub enum FnWithArgsOrAny<const N: usize> {
236 Any(Any),
237 FnWithArgs(FnWithArgs<N>),
238}
239impl<const N: usize> FnWithArgsOrAny<N> {
240 pub fn is_empty(&self) -> bool {
241 match self {
242 FnWithArgsOrAny::Any(a) => a.is_empty(),
243 FnWithArgsOrAny::FnWithArgs(fnwa) => fnwa.is_empty(),
244 }
245 }
246}
247impl<const N: usize> Default for FnWithArgsOrAny<N> {
248 fn default() -> Self {
249 FnWithArgsOrAny::Any(Any::from(false))
250 }
251}
252impl<const N: usize, T: Display> From<T> for FnWithArgsOrAny<N> {
253 fn from(s: T) -> Self {
254 Self::Any(s.to_string().into())
255 }
256}
257impl<const N: usize> From<FnWithArgs<N>> for FnWithArgsOrAny<N> {
258 fn from(value: FnWithArgs<N>) -> Self {
259 Self::FnWithArgs(value)
260 }
261}
262
263#[derive(Debug, Clone, Default, PartialEq, Eq)]
264pub struct NumberString(String);
265impl From<NumberOrDateString> for NumberString {
266 fn from(value: NumberOrDateString) -> Self {
267 value.0.into()
268 }
269}
270impl NumberString {
271 pub fn is_empty(&self) -> bool {
272 self.0.is_empty()
273 }
274}
275impl PartialOrd for NumberString {
276 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
277 Some(self.cmp(other))
278 }
279}
280impl Ord for NumberString {
281 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
282 if let Some((s, o)) = self
283 .0
284 .parse::<rust_decimal::Decimal>()
285 .ok()
286 .zip(other.0.parse::<rust_decimal::Decimal>().ok())
287 {
288 s.cmp(&o)
289 } else {
290 self.0.cmp(&other.0)
291 }
292 }
293}
294impl<T: Display> From<T> for NumberString {
295 fn from(s: T) -> Self {
296 Self(s.to_string())
297 }
298}
299#[allow(clippy::to_string_trait_impl)]
300impl ToString for NumberString {
301 fn to_string(&self) -> String {
302 self.0.to_string()
303 }
304}
305impl Serialize for NumberString {
306 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
307 where
308 S: serde::Serializer,
309 {
310 let fnum: Result<f64, _> = self.0.parse();
311 let inum: Result<i64, _> = self.0.parse();
312 match (fnum, inum) {
313 (Ok(_), Ok(inum)) => serializer.serialize_i64(inum),
314 (Ok(fnum), _) => serializer.serialize_f64(fnum),
315 _ => serializer.serialize_str(&self.0),
316 }
317 }
318}
319impl<'de> Deserialize<'de> for NumberString {
320 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
321 where
322 D: serde::Deserializer<'de>,
323 {
324 Any::deserialize(deserializer).map(|soi| Self(soi.to_string()))
325 }
326}
327
328#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize)]
329#[serde(untagged)]
330pub enum NumberStringOrT<T: Serialize + DeserializeOwned> {
331 T(T),
332 NumberString(NumberString),
333}
334impl<'de, T: Serialize + DeserializeOwned> Deserialize<'de> for NumberStringOrT<T> {
335 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
336 where
337 D: de::Deserializer<'de>,
338 {
339 let value = serde::__private::de::Content::deserialize(deserializer)?;
341 let deserializer = serde::__private::de::ContentRefDeserializer::<D::Error>::new(&value);
342
343 match NumberString::deserialize(deserializer) {
344 Ok(ns) => Ok(Self::NumberString(ns)),
345 Err(_) => T::deserialize(deserializer).map(Self::T),
346 }
347 }
348}
349impl<T: Serialize + DeserializeOwned> NumberStringOrT<T> {
350 pub fn is_empty(&self) -> bool {
351 match self {
352 NumberStringOrT::T(_t) => false,
353 NumberStringOrT::NumberString(ns) => ns.is_empty(),
354 }
355 }
356}
357
358impl<T: Serialize + ChartJsRsObject, U: Serialize + DeserializeOwned> From<T>
359 for NumberStringOrT<U>
360{
361 fn from(value: T) -> Self {
362 serde_json::from_value(serde_json::to_value(value).unwrap()).unwrap()
363 }
364}