1#[cfg(feature = "plotly_ndarray")]
2use ndarray::{Array, Ix2};
3use serde::Serialize;
4
5#[cfg(feature = "plotly_ndarray")]
6use crate::ndarray::ArrayTraces;
7
8pub fn owned_string_vector<S: AsRef<str>>(s: Vec<S>) -> Vec<String> {
9 s.iter()
10 .map(|x| x.as_ref().to_string())
11 .collect::<Vec<String>>()
12}
13
14#[derive(Serialize, Clone, Debug, PartialEq)]
15#[serde(untagged)]
16pub enum NumOrString {
17 S(String),
18 F(f64),
19 I(i64),
20 U(u64),
21}
22
23impl From<String> for NumOrString {
24 fn from(item: String) -> Self {
25 NumOrString::S(item)
26 }
27}
28
29impl From<&String> for NumOrString {
30 fn from(item: &String) -> Self {
31 NumOrString::S(item.clone())
32 }
33}
34
35impl From<&str> for NumOrString {
36 fn from(item: &str) -> Self {
37 NumOrString::S(item.to_string())
38 }
39}
40
41impl From<f64> for NumOrString {
42 fn from(item: f64) -> Self {
43 NumOrString::F(item)
44 }
45}
46
47impl From<f32> for NumOrString {
48 fn from(item: f32) -> Self {
49 NumOrString::F(item as f64)
50 }
51}
52
53impl From<usize> for NumOrString {
54 fn from(item: usize) -> Self {
55 NumOrString::U(item as u64)
56 }
57}
58
59impl From<u64> for NumOrString {
60 fn from(item: u64) -> Self {
61 NumOrString::U(item)
62 }
63}
64
65impl From<u32> for NumOrString {
66 fn from(item: u32) -> Self {
67 NumOrString::U(item as u64)
68 }
69}
70
71impl From<isize> for NumOrString {
72 fn from(item: isize) -> Self {
73 NumOrString::I(item as i64)
74 }
75}
76
77impl From<i64> for NumOrString {
78 fn from(item: i64) -> Self {
79 NumOrString::I(item)
80 }
81}
82
83impl From<i32> for NumOrString {
84 fn from(item: i32) -> Self {
85 NumOrString::I(item as i64)
86 }
87}
88
89#[derive(Serialize, Clone, Debug, PartialEq)]
90pub struct NumOrStringCollection(Vec<NumOrString>);
91
92impl<T> From<Vec<T>> for NumOrStringCollection
93where
94 T: Into<NumOrString> + Clone,
95{
96 fn from(items: Vec<T>) -> Self {
97 let mut collection: Vec<NumOrString> = Vec::with_capacity(items.len());
98 for item in items.iter().cloned() {
99 collection.push(item.into());
100 }
101 Self(collection)
102 }
103}
104
105#[cfg(feature = "plotly_ndarray")]
106pub fn trace_vectors_from<T>(traces_matrix: Array<T, Ix2>, array_traces: ArrayTraces) -> Vec<Vec<T>>
107where
108 T: Clone,
109{
110 let mut traces: Vec<Vec<T>> = Vec::new();
111 let dim_index = usize::from(array_traces == ArrayTraces::OverColumns);
112 let traces_count = traces_matrix.shape()[dim_index];
113 let get_trace = |index| {
114 if array_traces == ArrayTraces::OverColumns {
115 traces_matrix.column(index)
116 } else {
117 traces_matrix.row(index)
118 }
119 };
120 for col in 0..traces_count {
121 let trace_data: Vec<T> = get_trace(col).to_vec();
122 traces.push(trace_data);
123 }
124
125 traces
126}
127
128#[cfg(test)]
129mod tests {
130 use serde_json::{json, to_value};
131
132 use super::*;
133
134 #[test]
135 fn num_or_string() {
136 let x: NumOrString = "String".to_string().into();
137 assert_eq!(x, NumOrString::S("String".to_string()));
138
139 let x: NumOrString = (&"String".to_string()).into();
140 assert_eq!(x, NumOrString::S("String".to_string()));
141
142 let x: NumOrString = "&str".into();
143 assert_eq!(x, NumOrString::S("&str".to_string()));
144
145 let x: NumOrString = 100.0_f64.into();
146 assert_eq!(x, NumOrString::F(100.));
147
148 let x: NumOrString = 100.0_f32.into();
149 assert_eq!(x, NumOrString::F(100.));
150
151 let x: NumOrString = (-100_isize).into();
152 assert_eq!(x, NumOrString::I(-100));
153
154 let x: NumOrString = (-100_i64).into();
155 assert_eq!(x, NumOrString::I(-100));
156
157 let x: NumOrString = (-100_i32).into();
158 assert_eq!(x, NumOrString::I(-100));
159
160 let x: NumOrString = 100_usize.into();
161 assert_eq!(x, NumOrString::U(100));
162
163 let x: NumOrString = 100_u64.into();
164 assert_eq!(x, NumOrString::U(100));
165
166 let x: NumOrString = 100_u32.into();
167 assert_eq!(x, NumOrString::U(100));
168 }
169
170 #[test]
171 fn num_or_string_collection() {
172 let x: NumOrStringCollection = vec!["&str"].into();
173 let expected = NumOrStringCollection(vec![NumOrString::S("&str".to_string())]);
174 assert_eq!(x, expected);
175
176 let x: NumOrStringCollection = vec![1.].into();
177 let expected = NumOrStringCollection(vec![NumOrString::F(1.)]);
178 assert_eq!(x, expected);
179
180 let x: NumOrStringCollection = vec![1_i32].into();
181 let expected = NumOrStringCollection(vec![NumOrString::I(1)]);
182 assert_eq!(x, expected);
183
184 let x: NumOrStringCollection = vec![1_u32].into();
185 let expected = NumOrStringCollection(vec![NumOrString::U(1)]);
186 assert_eq!(x, expected);
187 }
188
189 #[test]
190 #[rustfmt::skip]
191 fn serialize_num_or_string() {
192 assert_eq!(to_value(NumOrString::S("&str".to_string())).unwrap(), json!("&str"));
193 assert_eq!(to_value(NumOrString::F(100.)).unwrap(), json!(100.0));
194 assert_eq!(to_value(NumOrString::I(-50)).unwrap(), json!(-50));
195 assert_eq!(to_value(NumOrString::U(50)).unwrap(), json!(50));
196 }
197
198 #[test]
199 #[rustfmt::skip]
200 fn serialize_num_or_string_collection() {
201 assert_eq!(to_value(NumOrStringCollection(vec![NumOrString::S("&str".to_string())])).unwrap(), json!(["&str"]));
202 assert_eq!(to_value(NumOrStringCollection(vec![NumOrString::F(100.)])).unwrap(), json!([100.0]));
203 assert_eq!(to_value(NumOrStringCollection(vec![NumOrString::I(-50)])).unwrap(), json!([-50]));
204 assert_eq!(to_value(NumOrStringCollection(vec![NumOrString::U(50)])).unwrap(), json!([50]));
205 }
206}