1use qubit_datatype::{
17 DataConversionError,
18 DataConversionOptions,
19 DataConvertTo,
20 DataConverter,
21 DataConverters,
22 DataListConversionError,
23 DataType,
24 ScalarStringDataConverters,
25};
26
27use crate::value_error::{
28 ValueError,
29 ValueResult,
30};
31use crate::{
32 IntoValueDefault,
33 Value,
34};
35
36use super::multi_values::MultiValues;
37
38macro_rules! multi_values_to_value_match {
39 ($value:expr; $(($variant:ident, $type:ty, $data_type:expr)),+ $(,)?) => {
40 match $value {
41 MultiValues::Empty(data_type) => Value::Empty(*data_type),
42 $(
43 MultiValues::$variant(values) => values
44 .first()
45 .cloned()
46 .map(Value::$variant)
47 .unwrap_or(Value::Empty($data_type)),
48 )+
49 }
50 };
51}
52
53macro_rules! multi_values_merge_match {
54 ($left:expr, $right:expr; $(($variant:ident, $type:ty, $data_type:expr)),+ $(,)?) => {
55 match ($left, $right) {
56 $(
57 (MultiValues::$variant(values), MultiValues::$variant(other_values)) => {
58 values.extend_from_slice(other_values)
59 }
60 )+
61 (slot @ MultiValues::Empty(_), other_values) => *slot = other_values.clone(),
62 _ => unreachable!(),
63 }
64 };
65}
66
67fn map_data_conversion_error(error: DataConversionError) -> ValueError {
81 match error {
82 DataConversionError::NoValue => ValueError::NoValue,
83 DataConversionError::ConversionFailed { from, to } => {
84 ValueError::ConversionFailed { from, to }
85 }
86 DataConversionError::ConversionError(message) => ValueError::ConversionError(message),
87 DataConversionError::JsonSerializationError(message) => {
88 ValueError::JsonSerializationError(message)
89 }
90 DataConversionError::JsonDeserializationError(message) => {
91 ValueError::JsonDeserializationError(message)
92 }
93 }
94}
95
96#[inline]
107fn map_data_list_conversion_error(error: DataListConversionError) -> ValueError {
108 let source = map_data_conversion_error(error.source);
109 ValueError::ConversionError(format!(
110 "Cannot convert value at index {}: {}",
111 error.index, source
112 ))
113}
114
115#[inline]
136fn convert_first_with<'a, T, I>(
137 values: DataConverters<'a, I>,
138 options: &DataConversionOptions,
139) -> ValueResult<T>
140where
141 DataConverter<'a>: DataConvertTo<T>,
142 I: Iterator,
143 I::Item: Into<DataConverter<'a>>,
144{
145 values
146 .to_first_with(options)
147 .map_err(map_data_conversion_error)
148}
149
150#[inline]
170fn convert_values_with<'a, T, I>(
171 values: DataConverters<'a, I>,
172 options: &DataConversionOptions,
173) -> ValueResult<Vec<T>>
174where
175 DataConverter<'a>: DataConvertTo<T>,
176 I: Iterator,
177 I::Item: Into<DataConverter<'a>>,
178{
179 values
180 .to_vec_with(options)
181 .map_err(map_data_list_conversion_error)
182}
183
184impl MultiValues {
185 #[inline]
204 pub fn to<T>(&self) -> ValueResult<T>
205 where
206 for<'a> DataConverter<'a>: DataConvertTo<T>,
207 {
208 self.to_with(&DataConversionOptions::default())
209 }
210
211 #[inline]
214 pub fn to_or<T>(&self, default: impl IntoValueDefault<T>) -> ValueResult<T>
215 where
216 for<'a> DataConverter<'a>: DataConvertTo<T>,
217 {
218 match self.to() {
219 Err(ValueError::NoValue) => Ok(default.into_value_default()),
220 result => result,
221 }
222 }
223
224 #[inline]
248 pub fn to_with<T>(&self, options: &DataConversionOptions) -> ValueResult<T>
249 where
250 for<'a> DataConverter<'a>: DataConvertTo<T>,
251 {
252 match self {
253 MultiValues::Empty(_) => Err(ValueError::NoValue),
254 MultiValues::Bool(v) => convert_first_with(DataConverters::from(v), options),
255 MultiValues::Char(v) => convert_first_with(DataConverters::from(v), options),
256 MultiValues::Int8(v) => convert_first_with(DataConverters::from(v), options),
257 MultiValues::Int16(v) => convert_first_with(DataConverters::from(v), options),
258 MultiValues::Int32(v) => convert_first_with(DataConverters::from(v), options),
259 MultiValues::Int64(v) => convert_first_with(DataConverters::from(v), options),
260 MultiValues::Int128(v) => convert_first_with(DataConverters::from(v), options),
261 MultiValues::UInt8(v) => convert_first_with(DataConverters::from(v), options),
262 MultiValues::UInt16(v) => convert_first_with(DataConverters::from(v), options),
263 MultiValues::UInt32(v) => convert_first_with(DataConverters::from(v), options),
264 MultiValues::UInt64(v) => convert_first_with(DataConverters::from(v), options),
265 MultiValues::UInt128(v) => convert_first_with(DataConverters::from(v), options),
266 MultiValues::IntSize(v) => convert_first_with(DataConverters::from(v), options),
267 MultiValues::UIntSize(v) => convert_first_with(DataConverters::from(v), options),
268 MultiValues::Float32(v) => convert_first_with(DataConverters::from(v), options),
269 MultiValues::Float64(v) => convert_first_with(DataConverters::from(v), options),
270 MultiValues::BigInteger(v) => convert_first_with(DataConverters::from(v), options),
271 MultiValues::BigDecimal(v) => convert_first_with(DataConverters::from(v), options),
272 MultiValues::String(v) if v.len() == 1 => {
273 ScalarStringDataConverters::from(v[0].as_str())
274 .to_first_with(options)
275 .map_err(map_data_conversion_error)
276 }
277 MultiValues::String(v) => convert_first_with(DataConverters::from(v), options),
278 MultiValues::Date(v) => convert_first_with(DataConverters::from(v), options),
279 MultiValues::Time(v) => convert_first_with(DataConverters::from(v), options),
280 MultiValues::DateTime(v) => convert_first_with(DataConverters::from(v), options),
281 MultiValues::Instant(v) => convert_first_with(DataConverters::from(v), options),
282 MultiValues::Duration(v) => convert_first_with(DataConverters::from(v), options),
283 MultiValues::Url(v) => convert_first_with(DataConverters::from(v), options),
284 MultiValues::StringMap(v) => convert_first_with(DataConverters::from(v), options),
285 MultiValues::Json(v) => convert_first_with(DataConverters::from(v), options),
286 }
287 }
288
289 #[inline]
292 pub fn to_or_with<T>(
293 &self,
294 default: impl IntoValueDefault<T>,
295 options: &DataConversionOptions,
296 ) -> ValueResult<T>
297 where
298 for<'a> DataConverter<'a>: DataConvertTo<T>,
299 {
300 match self.to_with(options) {
301 Err(ValueError::NoValue) => Ok(default.into_value_default()),
302 result => result,
303 }
304 }
305
306 pub fn to_list<T>(&self) -> ValueResult<Vec<T>>
325 where
326 for<'a> DataConverter<'a>: DataConvertTo<T>,
327 {
328 self.to_list_with(&DataConversionOptions::default())
329 }
330
331 #[inline]
334 pub fn to_list_or<T>(&self, default: impl IntoValueDefault<Vec<T>>) -> ValueResult<Vec<T>>
335 where
336 for<'a> DataConverter<'a>: DataConvertTo<T>,
337 {
338 let values = self.to_list()?;
339 if values.is_empty() {
340 Ok(default.into_value_default())
341 } else {
342 Ok(values)
343 }
344 }
345
346 pub fn to_list_with<T>(&self, options: &DataConversionOptions) -> ValueResult<Vec<T>>
370 where
371 for<'a> DataConverter<'a>: DataConvertTo<T>,
372 {
373 match self {
374 MultiValues::Empty(_) => Ok(Vec::new()),
375 MultiValues::Bool(v) => convert_values_with(DataConverters::from(v), options),
376 MultiValues::Char(v) => convert_values_with(DataConverters::from(v), options),
377 MultiValues::Int8(v) => convert_values_with(DataConverters::from(v), options),
378 MultiValues::Int16(v) => convert_values_with(DataConverters::from(v), options),
379 MultiValues::Int32(v) => convert_values_with(DataConverters::from(v), options),
380 MultiValues::Int64(v) => convert_values_with(DataConverters::from(v), options),
381 MultiValues::Int128(v) => convert_values_with(DataConverters::from(v), options),
382 MultiValues::UInt8(v) => convert_values_with(DataConverters::from(v), options),
383 MultiValues::UInt16(v) => convert_values_with(DataConverters::from(v), options),
384 MultiValues::UInt32(v) => convert_values_with(DataConverters::from(v), options),
385 MultiValues::UInt64(v) => convert_values_with(DataConverters::from(v), options),
386 MultiValues::UInt128(v) => convert_values_with(DataConverters::from(v), options),
387 MultiValues::IntSize(v) => convert_values_with(DataConverters::from(v), options),
388 MultiValues::UIntSize(v) => convert_values_with(DataConverters::from(v), options),
389 MultiValues::Float32(v) => convert_values_with(DataConverters::from(v), options),
390 MultiValues::Float64(v) => convert_values_with(DataConverters::from(v), options),
391 MultiValues::BigInteger(v) => convert_values_with(DataConverters::from(v), options),
392 MultiValues::BigDecimal(v) => convert_values_with(DataConverters::from(v), options),
393 MultiValues::String(v) if v.len() == 1 => {
394 ScalarStringDataConverters::from(v[0].as_str())
395 .to_vec_with(options)
396 .map_err(map_data_list_conversion_error)
397 }
398 MultiValues::String(v) => convert_values_with(DataConverters::from(v), options),
399 MultiValues::Date(v) => convert_values_with(DataConverters::from(v), options),
400 MultiValues::Time(v) => convert_values_with(DataConverters::from(v), options),
401 MultiValues::DateTime(v) => convert_values_with(DataConverters::from(v), options),
402 MultiValues::Instant(v) => convert_values_with(DataConverters::from(v), options),
403 MultiValues::Duration(v) => convert_values_with(DataConverters::from(v), options),
404 MultiValues::Url(v) => convert_values_with(DataConverters::from(v), options),
405 MultiValues::StringMap(v) => convert_values_with(DataConverters::from(v), options),
406 MultiValues::Json(v) => convert_values_with(DataConverters::from(v), options),
407 }
408 }
409
410 #[inline]
413 pub fn to_list_or_with<T>(
414 &self,
415 default: impl IntoValueDefault<Vec<T>>,
416 options: &DataConversionOptions,
417 ) -> ValueResult<Vec<T>>
418 where
419 for<'a> DataConverter<'a>: DataConvertTo<T>,
420 {
421 let values = self.to_list_with(options)?;
422 if values.is_empty() {
423 Ok(default.into_value_default())
424 } else {
425 Ok(values)
426 }
427 }
428
429 pub fn to_value(&self) -> Value {
438 for_each_multi_value_type!(multi_values_to_value_match, self)
439 }
440
441 pub fn merge(&mut self, other: &MultiValues) -> ValueResult<()> {
464 if self.data_type() != other.data_type() {
465 return Err(ValueError::TypeMismatch {
466 expected: self.data_type(),
467 actual: other.data_type(),
468 });
469 }
470 if other.count() == 0 {
471 return Ok(());
472 }
473
474 for_each_multi_value_type!(multi_values_merge_match, self, other);
475
476 Ok(())
477 }
478}
479
480impl Default for MultiValues {
481 #[inline]
482 fn default() -> Self {
483 MultiValues::Empty(DataType::String)
484 }
485}
486
487impl From<Value> for MultiValues {
488 fn from(value: Value) -> Self {
489 match value {
490 Value::Empty(dt) => MultiValues::Empty(dt),
491 Value::Bool(v) => MultiValues::Bool(vec![v]),
492 Value::Char(v) => MultiValues::Char(vec![v]),
493 Value::Int8(v) => MultiValues::Int8(vec![v]),
494 Value::Int16(v) => MultiValues::Int16(vec![v]),
495 Value::Int32(v) => MultiValues::Int32(vec![v]),
496 Value::Int64(v) => MultiValues::Int64(vec![v]),
497 Value::Int128(v) => MultiValues::Int128(vec![v]),
498 Value::UInt8(v) => MultiValues::UInt8(vec![v]),
499 Value::UInt16(v) => MultiValues::UInt16(vec![v]),
500 Value::UInt32(v) => MultiValues::UInt32(vec![v]),
501 Value::UInt64(v) => MultiValues::UInt64(vec![v]),
502 Value::UInt128(v) => MultiValues::UInt128(vec![v]),
503 Value::Float32(v) => MultiValues::Float32(vec![v]),
504 Value::Float64(v) => MultiValues::Float64(vec![v]),
505 Value::String(v) => MultiValues::String(vec![v]),
506 Value::Date(v) => MultiValues::Date(vec![v]),
507 Value::Time(v) => MultiValues::Time(vec![v]),
508 Value::DateTime(v) => MultiValues::DateTime(vec![v]),
509 Value::Instant(v) => MultiValues::Instant(vec![v]),
510 Value::BigInteger(v) => MultiValues::BigInteger(vec![v]),
511 Value::BigDecimal(v) => MultiValues::BigDecimal(vec![v]),
512 Value::IntSize(v) => MultiValues::IntSize(vec![v]),
513 Value::UIntSize(v) => MultiValues::UIntSize(vec![v]),
514 Value::Duration(v) => MultiValues::Duration(vec![v]),
515 Value::Url(v) => MultiValues::Url(vec![v]),
516 Value::StringMap(v) => MultiValues::StringMap(vec![v]),
517 Value::Json(v) => MultiValues::Json(vec![v]),
518 }
519 }
520}