1use qubit_datatype::{
17 DataConversionOptions,
18 DataConvertTo,
19 DataConverter,
20 DataConverters,
21 DataListConversionError,
22 DataType,
23 ScalarStringDataConverters,
24};
25
26use crate::value_error::{
27 ValueError,
28 ValueResult,
29 map_data_conversion_error,
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
67#[inline]
82fn map_data_list_conversion_error(error: DataListConversionError) -> ValueError {
83 let source = map_data_conversion_error(error.source);
84 ValueError::ConversionError(format!(
85 "Cannot convert value at index {}: {}",
86 error.index, source
87 ))
88}
89
90#[inline]
111fn convert_first_with<'a, T, I>(
112 values: DataConverters<'a, I>,
113 options: &DataConversionOptions,
114) -> ValueResult<T>
115where
116 DataConverter<'a>: DataConvertTo<T>,
117 I: Iterator,
118 I::Item: Into<DataConverter<'a>>,
119{
120 values
121 .to_first_with(options)
122 .map_err(map_data_conversion_error)
123}
124
125#[inline]
145fn convert_values_with<'a, T, I>(
146 values: DataConverters<'a, I>,
147 options: &DataConversionOptions,
148) -> ValueResult<Vec<T>>
149where
150 DataConverter<'a>: DataConvertTo<T>,
151 I: Iterator,
152 I::Item: Into<DataConverter<'a>>,
153{
154 values
155 .to_vec_with(options)
156 .map_err(map_data_list_conversion_error)
157}
158
159impl MultiValues {
160 #[inline]
179 pub fn to<T>(&self) -> ValueResult<T>
180 where
181 for<'a> DataConverter<'a>: DataConvertTo<T>,
182 {
183 self.to_with(&DataConversionOptions::default())
184 }
185
186 #[inline]
189 pub fn to_or<T>(&self, default: impl IntoValueDefault<T>) -> ValueResult<T>
190 where
191 for<'a> DataConverter<'a>: DataConvertTo<T>,
192 {
193 match self.to() {
194 Err(ValueError::NoValue) => Ok(default.into_value_default()),
195 result => result,
196 }
197 }
198
199 #[inline]
223 pub fn to_with<T>(&self, options: &DataConversionOptions) -> ValueResult<T>
224 where
225 for<'a> DataConverter<'a>: DataConvertTo<T>,
226 {
227 match self {
228 MultiValues::Empty(_) => Err(ValueError::NoValue),
229 MultiValues::Bool(v) => convert_first_with(DataConverters::from(v), options),
230 MultiValues::Char(v) => convert_first_with(DataConverters::from(v), options),
231 MultiValues::Int8(v) => convert_first_with(DataConverters::from(v), options),
232 MultiValues::Int16(v) => convert_first_with(DataConverters::from(v), options),
233 MultiValues::Int32(v) => convert_first_with(DataConverters::from(v), options),
234 MultiValues::Int64(v) => convert_first_with(DataConverters::from(v), options),
235 MultiValues::Int128(v) => convert_first_with(DataConverters::from(v), options),
236 MultiValues::UInt8(v) => convert_first_with(DataConverters::from(v), options),
237 MultiValues::UInt16(v) => convert_first_with(DataConverters::from(v), options),
238 MultiValues::UInt32(v) => convert_first_with(DataConverters::from(v), options),
239 MultiValues::UInt64(v) => convert_first_with(DataConverters::from(v), options),
240 MultiValues::UInt128(v) => convert_first_with(DataConverters::from(v), options),
241 MultiValues::IntSize(v) => convert_first_with(DataConverters::from(v), options),
242 MultiValues::UIntSize(v) => convert_first_with(DataConverters::from(v), options),
243 MultiValues::Float32(v) => convert_first_with(DataConverters::from(v), options),
244 MultiValues::Float64(v) => convert_first_with(DataConverters::from(v), options),
245 MultiValues::BigInteger(v) => convert_first_with(DataConverters::from(v), options),
246 MultiValues::BigDecimal(v) => convert_first_with(DataConverters::from(v), options),
247 MultiValues::String(v) if v.len() == 1 => {
248 ScalarStringDataConverters::from(v[0].as_str())
249 .to_first_with(options)
250 .map_err(map_data_conversion_error)
251 }
252 MultiValues::String(v) => convert_first_with(DataConverters::from(v), options),
253 MultiValues::Date(v) => convert_first_with(DataConverters::from(v), options),
254 MultiValues::Time(v) => convert_first_with(DataConverters::from(v), options),
255 MultiValues::DateTime(v) => convert_first_with(DataConverters::from(v), options),
256 MultiValues::Instant(v) => convert_first_with(DataConverters::from(v), options),
257 MultiValues::Duration(v) => convert_first_with(DataConverters::from(v), options),
258 MultiValues::Url(v) => convert_first_with(DataConverters::from(v), options),
259 MultiValues::StringMap(v) => convert_first_with(DataConverters::from(v), options),
260 MultiValues::Json(v) => convert_first_with(DataConverters::from(v), options),
261 }
262 }
263
264 #[inline]
267 pub fn to_or_with<T>(
268 &self,
269 default: impl IntoValueDefault<T>,
270 options: &DataConversionOptions,
271 ) -> ValueResult<T>
272 where
273 for<'a> DataConverter<'a>: DataConvertTo<T>,
274 {
275 match self.to_with(options) {
276 Err(ValueError::NoValue) => Ok(default.into_value_default()),
277 result => result,
278 }
279 }
280
281 pub fn to_list<T>(&self) -> ValueResult<Vec<T>>
300 where
301 for<'a> DataConverter<'a>: DataConvertTo<T>,
302 {
303 self.to_list_with(&DataConversionOptions::default())
304 }
305
306 #[inline]
309 pub fn to_list_or<T>(&self, default: impl IntoValueDefault<Vec<T>>) -> ValueResult<Vec<T>>
310 where
311 for<'a> DataConverter<'a>: DataConvertTo<T>,
312 {
313 let values = self.to_list()?;
314 if values.is_empty() {
315 Ok(default.into_value_default())
316 } else {
317 Ok(values)
318 }
319 }
320
321 pub fn to_list_with<T>(&self, options: &DataConversionOptions) -> ValueResult<Vec<T>>
345 where
346 for<'a> DataConverter<'a>: DataConvertTo<T>,
347 {
348 match self {
349 MultiValues::Empty(_) => Ok(Vec::new()),
350 MultiValues::Bool(v) => convert_values_with(DataConverters::from(v), options),
351 MultiValues::Char(v) => convert_values_with(DataConverters::from(v), options),
352 MultiValues::Int8(v) => convert_values_with(DataConverters::from(v), options),
353 MultiValues::Int16(v) => convert_values_with(DataConverters::from(v), options),
354 MultiValues::Int32(v) => convert_values_with(DataConverters::from(v), options),
355 MultiValues::Int64(v) => convert_values_with(DataConverters::from(v), options),
356 MultiValues::Int128(v) => convert_values_with(DataConverters::from(v), options),
357 MultiValues::UInt8(v) => convert_values_with(DataConverters::from(v), options),
358 MultiValues::UInt16(v) => convert_values_with(DataConverters::from(v), options),
359 MultiValues::UInt32(v) => convert_values_with(DataConverters::from(v), options),
360 MultiValues::UInt64(v) => convert_values_with(DataConverters::from(v), options),
361 MultiValues::UInt128(v) => convert_values_with(DataConverters::from(v), options),
362 MultiValues::IntSize(v) => convert_values_with(DataConverters::from(v), options),
363 MultiValues::UIntSize(v) => convert_values_with(DataConverters::from(v), options),
364 MultiValues::Float32(v) => convert_values_with(DataConverters::from(v), options),
365 MultiValues::Float64(v) => convert_values_with(DataConverters::from(v), options),
366 MultiValues::BigInteger(v) => convert_values_with(DataConverters::from(v), options),
367 MultiValues::BigDecimal(v) => convert_values_with(DataConverters::from(v), options),
368 MultiValues::String(v) if v.len() == 1 => {
369 ScalarStringDataConverters::from(v[0].as_str())
370 .to_vec_with(options)
371 .map_err(map_data_list_conversion_error)
372 }
373 MultiValues::String(v) => convert_values_with(DataConverters::from(v), options),
374 MultiValues::Date(v) => convert_values_with(DataConverters::from(v), options),
375 MultiValues::Time(v) => convert_values_with(DataConverters::from(v), options),
376 MultiValues::DateTime(v) => convert_values_with(DataConverters::from(v), options),
377 MultiValues::Instant(v) => convert_values_with(DataConverters::from(v), options),
378 MultiValues::Duration(v) => convert_values_with(DataConverters::from(v), options),
379 MultiValues::Url(v) => convert_values_with(DataConverters::from(v), options),
380 MultiValues::StringMap(v) => convert_values_with(DataConverters::from(v), options),
381 MultiValues::Json(v) => convert_values_with(DataConverters::from(v), options),
382 }
383 }
384
385 #[inline]
388 pub fn to_list_or_with<T>(
389 &self,
390 default: impl IntoValueDefault<Vec<T>>,
391 options: &DataConversionOptions,
392 ) -> ValueResult<Vec<T>>
393 where
394 for<'a> DataConverter<'a>: DataConvertTo<T>,
395 {
396 let values = self.to_list_with(options)?;
397 if values.is_empty() {
398 Ok(default.into_value_default())
399 } else {
400 Ok(values)
401 }
402 }
403
404 pub fn to_value(&self) -> Value {
413 for_each_multi_value_type!(multi_values_to_value_match, self)
414 }
415
416 pub fn merge(&mut self, other: &MultiValues) -> ValueResult<()> {
444 if self.data_type() != other.data_type() {
445 return Err(ValueError::TypeMismatch {
446 expected: self.data_type(),
447 actual: other.data_type(),
448 });
449 }
450 if other.count() == 0 {
451 return Ok(());
452 }
453
454 for_each_multi_value_type!(multi_values_merge_match, self, other);
455
456 Ok(())
457 }
458}
459
460impl Default for MultiValues {
461 #[inline]
462 fn default() -> Self {
463 MultiValues::Empty(DataType::String)
464 }
465}
466
467impl From<Value> for MultiValues {
468 fn from(value: Value) -> Self {
469 match value {
470 Value::Empty(dt) => MultiValues::Empty(dt),
471 Value::Bool(v) => MultiValues::Bool(vec![v]),
472 Value::Char(v) => MultiValues::Char(vec![v]),
473 Value::Int8(v) => MultiValues::Int8(vec![v]),
474 Value::Int16(v) => MultiValues::Int16(vec![v]),
475 Value::Int32(v) => MultiValues::Int32(vec![v]),
476 Value::Int64(v) => MultiValues::Int64(vec![v]),
477 Value::Int128(v) => MultiValues::Int128(vec![v]),
478 Value::UInt8(v) => MultiValues::UInt8(vec![v]),
479 Value::UInt16(v) => MultiValues::UInt16(vec![v]),
480 Value::UInt32(v) => MultiValues::UInt32(vec![v]),
481 Value::UInt64(v) => MultiValues::UInt64(vec![v]),
482 Value::UInt128(v) => MultiValues::UInt128(vec![v]),
483 Value::Float32(v) => MultiValues::Float32(vec![v]),
484 Value::Float64(v) => MultiValues::Float64(vec![v]),
485 Value::String(v) => MultiValues::String(vec![v]),
486 Value::Date(v) => MultiValues::Date(vec![v]),
487 Value::Time(v) => MultiValues::Time(vec![v]),
488 Value::DateTime(v) => MultiValues::DateTime(vec![v]),
489 Value::Instant(v) => MultiValues::Instant(vec![v]),
490 Value::BigInteger(v) => MultiValues::BigInteger(vec![v]),
491 Value::BigDecimal(v) => MultiValues::BigDecimal(vec![v]),
492 Value::IntSize(v) => MultiValues::IntSize(vec![v]),
493 Value::UIntSize(v) => MultiValues::UIntSize(vec![v]),
494 Value::Duration(v) => MultiValues::Duration(vec![v]),
495 Value::Url(v) => MultiValues::Url(vec![v]),
496 Value::StringMap(v) => MultiValues::StringMap(vec![v]),
497 Value::Json(v) => MultiValues::Json(vec![v]),
498 }
499 }
500}