charming_fork_zephyr/series/
theme_river.rs1use serde::{ser::SerializeSeq, Serialize};
2
3use crate::{
4 datatype::CompositeValue,
5 element::{BoundaryGap, ColorBy, CoordinateSystem, Label},
6};
7
8pub struct ThemeRiverData {
9 date: CompositeValue,
10 value: CompositeValue,
11 name: CompositeValue,
12}
13
14impl ThemeRiverData {
15 pub fn new<D, V, N>(date: D, value: V, name: N) -> Self
16 where
17 D: Into<CompositeValue>,
18 V: Into<CompositeValue>,
19 N: Into<CompositeValue>,
20 {
21 Self {
22 date: date.into(),
23 value: value.into(),
24 name: name.into(),
25 }
26 }
27}
28
29impl Serialize for ThemeRiverData {
30 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
31 let mut s = serializer.serialize_seq(None)?;
32 s.serialize_element(&self.date)?;
33 s.serialize_element(&self.value)?;
34 s.serialize_element(&self.name)?;
35 s.end()
36 }
37}
38
39impl<D, V, N> From<(D, V, N)> for ThemeRiverData
40where
41 D: Into<CompositeValue>,
42 V: Into<CompositeValue>,
43 N: Into<CompositeValue>,
44{
45 fn from(v: (D, V, N)) -> Self {
46 Self::new(v.0, v.1, v.2)
47 }
48}
49
50#[derive(Serialize)]
51#[serde(rename_all = "camelCase")]
52pub struct ThemeRiver {
53 #[serde(rename = "type")]
54 type_: String,
55
56 #[serde(skip_serializing_if = "Option::is_none")]
57 id: Option<String>,
58
59 #[serde(skip_serializing_if = "Option::is_none")]
60 name: Option<String>,
61
62 #[serde(skip_serializing_if = "Option::is_none")]
63 color_by: Option<ColorBy>,
64
65 #[serde(skip_serializing_if = "Option::is_none")]
66 left: Option<CompositeValue>,
67
68 #[serde(skip_serializing_if = "Option::is_none")]
69 top: Option<CompositeValue>,
70
71 #[serde(skip_serializing_if = "Option::is_none")]
72 right: Option<CompositeValue>,
73
74 #[serde(skip_serializing_if = "Option::is_none")]
75 bottom: Option<CompositeValue>,
76
77 #[serde(skip_serializing_if = "Option::is_none")]
78 width: Option<CompositeValue>,
79
80 #[serde(skip_serializing_if = "Option::is_none")]
81 height: Option<CompositeValue>,
82
83 #[serde(skip_serializing_if = "Option::is_none")]
84 coordinate_system: Option<CoordinateSystem>,
85
86 #[serde(skip_serializing_if = "Option::is_none")]
87 boundary_gap: Option<BoundaryGap>,
88
89 #[serde(skip_serializing_if = "Option::is_none")]
90 label: Option<Label>,
91
92 #[serde(skip_serializing_if = "Vec::is_empty")]
93 data: Vec<ThemeRiverData>,
94}
95
96impl ThemeRiver {
97 pub fn new() -> Self {
98 Self {
99 type_: "themeRiver".to_string(),
100 id: None,
101 name: None,
102 color_by: None,
103 left: None,
104 top: None,
105 right: None,
106 bottom: None,
107 width: None,
108 height: None,
109 coordinate_system: None,
110 boundary_gap: None,
111 label: None,
112 data: vec![],
113 }
114 }
115
116 pub fn id<S: Into<String>>(mut self, id: S) -> Self {
117 self.id = Some(id.into());
118 self
119 }
120
121 pub fn name<S: Into<String>>(mut self, name: S) -> Self {
122 self.name = Some(name.into());
123 self
124 }
125
126 pub fn color_by(mut self, color_by: ColorBy) -> Self {
127 self.color_by = Some(color_by);
128 self
129 }
130
131 pub fn left<C: Into<CompositeValue>>(mut self, left: C) -> Self {
132 self.left = Some(left.into());
133 self
134 }
135
136 pub fn top<C: Into<CompositeValue>>(mut self, top: C) -> Self {
137 self.top = Some(top.into());
138 self
139 }
140
141 pub fn right<C: Into<CompositeValue>>(mut self, right: C) -> Self {
142 self.right = Some(right.into());
143 self
144 }
145
146 pub fn bottom<C: Into<CompositeValue>>(mut self, bottom: C) -> Self {
147 self.bottom = Some(bottom.into());
148 self
149 }
150
151 pub fn width<C: Into<CompositeValue>>(mut self, width: C) -> Self {
152 self.width = Some(width.into());
153 self
154 }
155
156 pub fn height<C: Into<CompositeValue>>(mut self, height: C) -> Self {
157 self.height = Some(height.into());
158 self
159 }
160
161 pub fn coordinate_system<C: Into<CoordinateSystem>>(mut self, coordinate_system: C) -> Self {
162 self.coordinate_system = Some(coordinate_system.into());
163 self
164 }
165
166 pub fn boundary_gap<B: Into<BoundaryGap>>(mut self, boundary_gap: B) -> Self {
167 self.boundary_gap = Some(boundary_gap.into());
168 self
169 }
170
171 pub fn label<L: Into<Label>>(mut self, label: L) -> Self {
172 self.label = Some(label.into());
173 self
174 }
175
176 pub fn data<T: Into<ThemeRiverData>>(mut self, data: Vec<T>) -> Self {
177 self.data = data.into_iter().map(|d| d.into()).collect();
178 self
179 }
180}