1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use super::{DimElement, Name};
use core::ops::{Deref, DerefMut};
#[derive(Clone, Debug, PartialEq)]
pub enum MaybeArray<T> {
Single(T),
Array(T, DimElement),
}
impl<T> Deref for MaybeArray<T> {
type Target = T;
fn deref(&self) -> &T {
match self {
Self::Single(info) => info,
Self::Array(info, _) => info,
}
}
}
impl<T> DerefMut for MaybeArray<T> {
fn deref_mut(&mut self) -> &mut T {
match self {
Self::Single(info) => info,
Self::Array(info, _) => info,
}
}
}
impl<T> MaybeArray<T> {
pub const fn is_single(&self) -> bool {
matches!(self, Self::Single(_))
}
pub const fn is_array(&self) -> bool {
matches!(self, Self::Array(_, _))
}
}
impl<T> Name for MaybeArray<T>
where
T: Name,
{
fn name(&self) -> &str {
T::name(self)
}
}
pub fn names<'a, T: Name>(info: &'a T, dim: &'a DimElement) -> impl Iterator<Item = String> + 'a {
let name = info.name();
dim.indexes()
.map(move |i| name.replace("[%s]", &i).replace("%s", &i))
}
#[cfg(feature = "serde")]
mod ser_de {
use super::*;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[derive(serde::Serialize)]
struct SerArray<'a, T> {
#[serde(flatten)]
dim: &'a DimElement,
#[serde(flatten)]
info: &'a T,
}
#[derive(serde::Deserialize)]
struct DeserArray<T> {
#[serde(flatten, default)]
dim: Option<DimElement>,
#[serde(flatten)]
info: T,
}
impl<T> Serialize for MaybeArray<T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
Self::Single(info) => info.serialize(serializer),
Self::Array(info, dim) => SerArray::<T> { dim, info }.serialize(serializer),
}
}
}
impl<'de, T> Deserialize<'de> for MaybeArray<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let DeserArray { dim, info } = DeserArray::<T>::deserialize(deserializer)?;
if let Some(dim) = dim {
Ok(Self::Array(info, dim))
} else {
Ok(Self::Single(info))
}
}
}
}