1use std::fmt::Display;
2
3use chrono::{DateTime, NaiveDate, Utc};
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6
7use crate::{
8 Array,
9 array::Constraint,
10 array_type,
11 validate::{Validate, Validator},
12};
13
14#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
19#[serde(untagged)]
20pub enum NumberRange {
21 Float {
22 min: f64,
23 max: f64,
24 },
25 Integer {
26 min: i64,
27 max: i64,
28 },
29 Date {
30 min: NaiveDate,
31 max: NaiveDate,
32 },
33 DateTime {
34 min: DateTime<Utc>,
35 max: DateTime<Utc>,
36 },
37}
38
39impl Display for NumberRange {
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 match self {
42 NumberRange::Float { min, max } => write!(f, "[{min}, {max}]"),
43 NumberRange::Integer { min, max } => write!(f, "[{min}, {max}]"),
44 NumberRange::Date { min, max } => write!(f, "[{min}, {max}]"),
45 NumberRange::DateTime { min, max } => write!(f, "[{min}, {max}]"),
46 }
47 }
48}
49
50impl From<(f64, f64)> for NumberRange {
51 fn from((min, max): (f64, f64)) -> Self {
52 Self::Float { min, max }
53 }
54}
55
56impl From<(i64, i64)> for NumberRange {
57 fn from((min, max): (i64, i64)) -> Self {
58 Self::Integer { min, max }
59 }
60}
61
62impl From<(i32, i32)> for NumberRange {
63 fn from((min, max): (i32, i32)) -> Self {
64 Self::Integer {
65 min: min.into(),
66 max: max.into(),
67 }
68 }
69}
70
71impl From<(NaiveDate, NaiveDate)> for NumberRange {
72 fn from((min, max): (NaiveDate, NaiveDate)) -> Self {
73 Self::Date { min, max }
74 }
75}
76
77impl From<(DateTime<Utc>, DateTime<Utc>)> for NumberRange {
78 fn from((min, max): (DateTime<Utc>, DateTime<Utc>)) -> Self {
79 Self::DateTime { min, max }
80 }
81}
82
83#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
85#[serde(tag = "type")]
86pub enum NumberColormap {
87 Continuous {
98 range: NumberRange,
100 gradient: Array<array_type::Gradient>,
102 },
103 Discrete {
108 boundaries: Array<array_type::Boundary>,
112 gradient: Array<array_type::Gradient>,
116 },
117}
118
119impl Validate for NumberColormap {
120 fn validate_inner(&mut self, val: &mut Validator) {
121 match self {
122 NumberColormap::Continuous { range, gradient } => {
123 val.enter("NumberColormap::Continuous")
124 .min_max(*range)
125 .array(gradient, Constraint::Gradient, "gradient");
126 }
127 NumberColormap::Discrete {
128 boundaries,
129 gradient,
130 } => {
131 val.enter("NumberColormap::Discrete")
132 .array(boundaries, Constraint::Boundary, "boundaries")
133 .array(gradient, Constraint::Gradient, "gradient")
134 .array_size(
135 gradient.item_count(),
136 boundaries.item_count() + 1,
137 "gradient",
138 );
139 }
140 }
141 }
142}