plotly/
private.rs

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}