qubit_value/multi_values/
multi_values.rs1use qubit_datatype::DataType;
16use std::fmt;
17
18use super::multi_values_ref::MultiValuesRef;
19
20macro_rules! define_multi_values_enum {
23 (
24 ;
25 $(
26 (
27 [$($cfg:meta),*],
28 $variant:ident,
29 $type:ty,
30 $data_type:expr,
31 $materialization:ident,
32 $json_class:ident,
33 $number_projection:ident,
34 $value_doc:literal,
35 $multi_doc:literal
36 )
37 ),+ $(,)?
38 ) => {
39 #[derive(Debug, Clone)]
79 pub(crate) enum MultiValuesRepr {
80 Unset(
82 DataType,
84 ),
85 $(
86 $(#[$cfg])*
87 #[doc = $multi_doc]
88 $variant(
89 #[doc = concat!("Stored ", $multi_doc, " payload.")]
90 Vec<$type>,
91 ),
92 )+
93 }
94 };
95}
96
97for_each_value_type!(define_multi_values_enum);
98
99#[must_use]
101#[derive(Clone)]
102pub struct MultiValues {
103 pub(crate) repr: MultiValuesRepr,
104}
105
106impl fmt::Debug for MultiValues {
107 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
108 self.view().fmt(formatter)
109 }
110}
111
112macro_rules! impl_multi_values_constructors {
113 (
114 ;
115 $(
116 (
117 [$($cfg:meta),*],
118 $variant:ident,
119 $type:ty,
120 $data_type:expr,
121 $materialization:ident,
122 $json_class:ident,
123 $number_projection:ident,
124 $value_doc:literal,
125 $multi_doc:literal
126 )
127 ),+ $(,)?
128 ) => {
129 impl MultiValues {
130 #[allow(non_snake_case)]
132 #[inline(always)]
133 pub const fn Unset(data_type: DataType) -> Self {
134 Self::new_unset(data_type)
135 }
136
137 #[inline(always)]
139 pub const fn new_unset(data_type: DataType) -> Self {
140 Self { repr: MultiValuesRepr::Unset(data_type) }
141 }
142
143 $(
144 $(#[$cfg])*
145 #[allow(non_snake_case)]
146 #[doc = concat!("Creates a collection of ", $multi_doc, ".")]
147 #[inline(always)]
148 pub fn $variant(values: Vec<$type>) -> Self {
149 Self { repr: MultiValuesRepr::$variant(values) }
150 }
151 )+
152 }
153 };
154}
155
156for_each_value_type!(impl_multi_values_constructors);
157
158impl MultiValues {
159 #[inline(always)]
161 pub fn view(&self) -> MultiValuesRef<'_> {
162 match &self.repr {
163 MultiValuesRepr::Unset(data_type) => {
164 MultiValuesRef::Unset(*data_type)
165 }
166 MultiValuesRepr::Bool(values) => MultiValuesRef::Bool(values),
167 MultiValuesRepr::Char(values) => MultiValuesRef::Char(values),
168 MultiValuesRepr::Int8(values) => MultiValuesRef::Int8(values),
169 MultiValuesRepr::Int16(values) => MultiValuesRef::Int16(values),
170 MultiValuesRepr::Int32(values) => MultiValuesRef::Int32(values),
171 MultiValuesRepr::Int64(values) => MultiValuesRef::Int64(values),
172 MultiValuesRepr::Int128(values) => MultiValuesRef::Int128(values),
173 MultiValuesRepr::UInt8(values) => MultiValuesRef::UInt8(values),
174 MultiValuesRepr::UInt16(values) => MultiValuesRef::UInt16(values),
175 MultiValuesRepr::UInt32(values) => MultiValuesRef::UInt32(values),
176 MultiValuesRepr::UInt64(values) => MultiValuesRef::UInt64(values),
177 MultiValuesRepr::UInt128(values) => MultiValuesRef::UInt128(values),
178 MultiValuesRepr::Float32(values) => MultiValuesRef::Float32(values),
179 MultiValuesRepr::Float64(values) => MultiValuesRef::Float64(values),
180 #[cfg(feature = "big-integer")]
181 MultiValuesRepr::BigInteger(values) => {
182 MultiValuesRef::BigInteger(values)
183 }
184 #[cfg(feature = "big-decimal")]
185 MultiValuesRepr::BigDecimal(values) => {
186 MultiValuesRef::BigDecimal(values)
187 }
188 MultiValuesRepr::String(values) => MultiValuesRef::String(values),
189 #[cfg(feature = "chrono")]
190 MultiValuesRepr::Date(values) => MultiValuesRef::Date(values),
191 #[cfg(feature = "chrono")]
192 MultiValuesRepr::Time(values) => MultiValuesRef::Time(values),
193 #[cfg(feature = "chrono")]
194 MultiValuesRepr::DateTime(values) => {
195 MultiValuesRef::DateTime(values)
196 }
197 #[cfg(feature = "chrono")]
198 MultiValuesRepr::Instant(values) => MultiValuesRef::Instant(values),
199 MultiValuesRepr::Duration(values) => {
200 MultiValuesRef::Duration(values)
201 }
202 #[cfg(feature = "url")]
203 MultiValuesRepr::Url(values) => MultiValuesRef::Url(values),
204 MultiValuesRepr::StringMap(values) => {
205 MultiValuesRef::StringMap(values)
206 }
207 #[cfg(feature = "json")]
208 MultiValuesRepr::Json(values) => MultiValuesRef::Json(values),
209 }
210 }
211}
212
213macro_rules! impl_get_multi_values {
227 ($(#[$attr:meta])* slice: $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
229 $(#[$attr])*
230 #[doc = ""]
231 #[doc = "# Errors"]
232 #[doc = ""]
233 #[doc = "Returns [`ValueError::Missing`] when the container is unset"]
234 #[doc = "with the requested type, or [`ValueError::TypeMismatch`] when"]
235 #[doc = "the stored data type differs. A concrete empty vector returns"]
236 #[doc = "an empty slice."]
237 #[inline(always)]
238 pub fn $method(&self) -> ValueResult<&[$type]> {
239 match &self.repr {
240 MultiValuesRepr::$variant(v) => Ok(v),
241 MultiValuesRepr::Unset(dt) if *dt == $data_type => {
242 Err(ValueError::Missing($crate::ValueMissing::UnsetCollection {
243 data_type: *dt,
244 }))
245 }
246 _ => Err(ValueError::TypeMismatch {
247 expected: $data_type,
248 actual: self.data_type(),
249 }),
250 }
251 }
252 };
253
254 ($(#[$attr:meta])* vec: $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
256 $(#[$attr])*
257 #[doc = ""]
258 #[doc = "# Errors"]
259 #[doc = ""]
260 #[doc = "Returns [`ValueError::Missing`] when the container is unset"]
261 #[doc = "with the requested type, or [`ValueError::TypeMismatch`] when"]
262 #[doc = "the stored data type differs. A concrete empty vector returns"]
263 #[doc = "an empty slice."]
264 #[inline(always)]
265 pub fn $method(&self) -> ValueResult<&[$type]> {
266 match &self.repr {
267 MultiValuesRepr::$variant(v) => Ok(v.as_slice()),
268 MultiValuesRepr::Unset(dt) if *dt == $data_type => {
269 Err(ValueError::Missing($crate::ValueMissing::UnsetCollection {
270 data_type: *dt,
271 }))
272 }
273 _ => Err(ValueError::TypeMismatch {
274 expected: $data_type,
275 actual: self.data_type(),
276 }),
277 }
278 }
279 };
280}
281
282macro_rules! impl_get_first_value {
292 ($(#[$attr:meta])* copy: $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
294 $(#[$attr])*
295 #[doc = ""]
296 #[doc = "# Errors"]
297 #[doc = ""]
298 #[doc = "Returns [`ValueError::Missing`] when the requested type matches"]
299 #[doc = "but no value is stored, or [`ValueError::TypeMismatch`] when"]
300 #[doc = "the stored data type differs."]
301 #[inline(always)]
302 pub fn $method(&self) -> ValueResult<$type> {
303 match &self.repr {
304 MultiValuesRepr::$variant(v) if !v.is_empty() => Ok(v[0]),
305 MultiValuesRepr::$variant(_) => {
306 Err(ValueError::Missing($crate::ValueMissing::EmptyCollection {
307 data_type: $data_type,
308 }))
309 }
310 MultiValuesRepr::Unset(dt) if *dt == $data_type => {
311 Err(ValueError::Missing($crate::ValueMissing::UnsetCollection {
312 data_type: *dt,
313 }))
314 }
315 _ => Err(ValueError::TypeMismatch {
316 expected: $data_type,
317 actual: self.data_type(),
318 }),
319 }
320 }
321 };
322
323 ($(#[$attr:meta])* ref: $method:ident, $variant:ident, $ret_type:ty, $data_type:expr, $conversion:expr) => {
325 $(#[$attr])*
326 #[doc = ""]
327 #[doc = "# Errors"]
328 #[doc = ""]
329 #[doc = "Returns [`ValueError::Missing`] when the requested type matches"]
330 #[doc = "but no value is stored, or [`ValueError::TypeMismatch`] when"]
331 #[doc = "the stored data type differs."]
332 #[inline(always)]
333 pub fn $method(&self) -> ValueResult<$ret_type> {
334 match &self.repr {
335 MultiValuesRepr::$variant(v) if !v.is_empty() => {
336 let conv_fn: fn(&_) -> $ret_type = $conversion;
337 Ok(conv_fn(&v[0]))
338 },
339 MultiValuesRepr::$variant(_) => {
340 Err(ValueError::Missing($crate::ValueMissing::EmptyCollection {
341 data_type: $data_type,
342 }))
343 }
344 MultiValuesRepr::Unset(dt) if *dt == $data_type => {
345 Err(ValueError::Missing($crate::ValueMissing::UnsetCollection {
346 data_type: *dt,
347 }))
348 }
349 _ => Err(ValueError::TypeMismatch {
350 expected: $data_type,
351 actual: self.data_type(),
352 }),
353 }
354 }
355 };
356}