1use super::{Description, DimElement, Name};
2use core::ops::{Deref, DerefMut};
3
4#[derive(Clone, Debug, PartialEq, Eq)]
6pub enum MaybeArray<T> {
7 Single(T),
9 Array(T, DimElement),
11}
12
13impl<T> Deref for MaybeArray<T> {
14 type Target = T;
15
16 fn deref(&self) -> &T {
17 match self {
18 Self::Single(info) => info,
19 Self::Array(info, _) => info,
20 }
21 }
22}
23
24impl<T> DerefMut for MaybeArray<T> {
25 fn deref_mut(&mut self) -> &mut T {
26 match self {
27 Self::Single(info) => info,
28 Self::Array(info, _) => info,
29 }
30 }
31}
32
33impl<T> MaybeArray<T> {
34 pub const fn is_single(&self) -> bool {
36 matches!(self, Self::Single(_))
37 }
38 pub const fn is_array(&self) -> bool {
40 matches!(self, Self::Array(_, _))
41 }
42}
43
44impl<T> Name for MaybeArray<T>
45where
46 T: Name,
47{
48 fn name(&self) -> &str {
49 T::name(self)
50 }
51}
52
53impl<T> Description for MaybeArray<T>
54where
55 T: Description,
56{
57 fn description(&self) -> Option<&str> {
58 T::description(self)
59 }
60}
61
62pub fn names<'a, T: Name>(info: &'a T, dim: &'a DimElement) -> impl Iterator<Item = String> + 'a {
64 let name = info.name();
65 dim.indexes().map(move |i| {
66 dim.dim_array_index
67 .as_ref()
68 .and_then(|dai| {
69 dai.values
70 .iter()
71 .find(|e| e.value.map(|v| v.to_string().as_str() == i.deref()) == Some(true))
72 })
73 .map(|n| n.name.clone())
74 .unwrap_or_else(|| name.replace("[%s]", &i).replace("%s", &i))
75 })
76}
77
78pub fn descriptions<'a, T: Description>(
80 info: &'a T,
81 dim: &'a DimElement,
82) -> impl Iterator<Item = Option<String>> + 'a {
83 let description = info.description();
84 dim.indexes().map(move |i| {
85 dim.dim_array_index
86 .as_ref()
87 .and_then(|dai| {
88 dai.values
89 .iter()
90 .find(|e| e.value.map(|v| v.to_string().as_str() == i.deref()) == Some(true))
91 })
92 .and_then(|n| n.description.clone())
93 .or_else(|| description.map(|d| d.replace("[%s]", &i).replace("%s", &i)))
94 })
95}
96
97#[cfg(feature = "serde")]
98mod ser_de {
99 use super::*;
100 use serde::{Deserialize, Deserializer, Serialize, Serializer};
101
102 #[derive(serde::Serialize)]
103 struct SerArray<'a, T> {
104 #[serde(flatten)]
105 dim: &'a DimElement,
106 #[serde(flatten)]
107 info: &'a T,
108 }
109
110 #[derive(serde::Deserialize)]
111 struct DeserArray<T> {
112 #[serde(flatten, default)]
113 dim: Option<DimElement>,
114 #[serde(flatten)]
115 info: T,
116 }
117
118 impl<T> Serialize for MaybeArray<T>
119 where
120 T: Serialize,
121 {
122 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
123 where
124 S: Serializer,
125 {
126 match self {
127 Self::Single(info) => info.serialize(serializer),
128 Self::Array(info, dim) => SerArray::<T> { dim, info }.serialize(serializer),
129 }
130 }
131 }
132
133 impl<'de, T> Deserialize<'de> for MaybeArray<T>
134 where
135 T: Deserialize<'de>,
136 {
137 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
138 where
139 D: Deserializer<'de>,
140 {
141 let DeserArray { dim, info } = DeserArray::<T>::deserialize(deserializer)?;
142 if let Some(dim) = dim {
143 Ok(Self::Array(info, dim))
144 } else {
145 Ok(Self::Single(info))
146 }
147 }
148 }
149}