use qubit_datatype::{
DataConversionError,
DataConversionOptions,
DataConversionTarget,
DataConverter,
DataConverters,
};
use crate::IntoValueDefault;
use crate::value_error::{
ValueError,
ValueResult,
};
use super::multi_values::{
MultiValues,
MultiValuesRepr,
};
macro_rules! multi_values_convert_first_match {
($value:expr, $options:expr; $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal)),+ $(,)?) => {
match &$value.repr {
MultiValuesRepr::Unset(from) => {
Err(DataConversionError::missing(*from, T::DATA_TYPE).into())
}
$(
$(#[$cfg])*
MultiValuesRepr::$variant(values) => {
convert_first_with(DataConverters::from(values), $options)
}
)+
}
};
}
macro_rules! multi_values_convert_list_match {
($value:expr, $options:expr; $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal)),+ $(,)?) => {
match &$value.repr {
MultiValuesRepr::Unset(from) => {
Err(DataConversionError::missing(*from, T::DATA_TYPE).into())
}
$(
$(#[$cfg])*
MultiValuesRepr::$variant(values) => {
convert_values_with(DataConverters::from(values), $options)
}
)+
}
};
}
#[inline(always)]
fn convert_first_with<'a, T, I>(
values: DataConverters<I>,
options: &DataConversionOptions,
) -> ValueResult<T>
where
T: DataConversionTarget,
I: Iterator,
I::Item: Into<DataConverter<'a>>,
{
values.to_first_with(options).map_err(ValueError::from)
}
#[inline(always)]
fn convert_values_with<'a, T, I>(
values: DataConverters<I>,
options: &DataConversionOptions,
) -> ValueResult<Vec<T>>
where
T: DataConversionTarget,
I: Iterator,
I::Item: Into<DataConverter<'a>>,
{
values.to_vec_with(options).map_err(ValueError::from)
}
impl MultiValues {
#[inline(always)]
pub fn to_first<T>(&self) -> ValueResult<T>
where
T: DataConversionTarget,
{
self.to_first_with(DataConversionOptions::default_ref())
}
#[inline]
pub fn to_first_or<T>(
&self,
default: impl IntoValueDefault<T>,
) -> ValueResult<T>
where
T: DataConversionTarget,
{
match self.to_first() {
Err(ValueError::Missing(missing))
if missing.is_defaultable_for_conversion() =>
{
Ok(default.into_value_default())
}
result => result,
}
}
#[inline]
pub fn to_first_or_else<T, F>(&self, default: F) -> ValueResult<T>
where
T: DataConversionTarget,
F: FnOnce() -> T,
{
match self.to_first() {
Err(ValueError::Missing(missing))
if missing.is_defaultable_for_conversion() =>
{
Ok(default())
}
result => result,
}
}
pub fn to_first_with<T>(
&self,
options: &DataConversionOptions,
) -> ValueResult<T>
where
T: DataConversionTarget,
{
for_each_value_type!(multi_values_convert_first_match, self, options)
}
#[inline]
pub fn to_first_or_with<T>(
&self,
default: impl IntoValueDefault<T>,
options: &DataConversionOptions,
) -> ValueResult<T>
where
T: DataConversionTarget,
{
match self.to_first_with(options) {
Err(ValueError::Missing(missing))
if missing.is_defaultable_for_conversion() =>
{
Ok(default.into_value_default())
}
result => result,
}
}
#[inline]
pub fn to_first_or_else_with<T, F>(
&self,
default: F,
options: &DataConversionOptions,
) -> ValueResult<T>
where
T: DataConversionTarget,
F: FnOnce() -> T,
{
match self.to_first_with(options) {
Err(ValueError::Missing(missing))
if missing.is_defaultable_for_conversion() =>
{
Ok(default())
}
result => result,
}
}
pub fn to_list<T>(&self) -> ValueResult<Vec<T>>
where
T: DataConversionTarget,
{
self.to_list_with(DataConversionOptions::default_ref())
}
#[inline]
pub fn to_list_or<T>(
&self,
default: impl IntoValueDefault<Vec<T>>,
) -> ValueResult<Vec<T>>
where
T: DataConversionTarget,
{
match self.to_list() {
Err(ValueError::Missing(missing))
if missing.is_defaultable_for_conversion() =>
{
Ok(default.into_value_default())
}
result => result,
}
}
#[inline]
pub fn to_list_or_else<T, F>(&self, default: F) -> ValueResult<Vec<T>>
where
T: DataConversionTarget,
F: FnOnce() -> Vec<T>,
{
match self.to_list() {
Err(ValueError::Missing(missing))
if missing.is_defaultable_for_conversion() =>
{
Ok(default())
}
result => result,
}
}
pub fn to_list_with<T>(
&self,
options: &DataConversionOptions,
) -> ValueResult<Vec<T>>
where
T: DataConversionTarget,
{
for_each_value_type!(multi_values_convert_list_match, self, options)
}
#[inline]
pub fn to_list_or_with<T>(
&self,
default: impl IntoValueDefault<Vec<T>>,
options: &DataConversionOptions,
) -> ValueResult<Vec<T>>
where
T: DataConversionTarget,
{
match self.to_list_with(options) {
Err(ValueError::Missing(missing))
if missing.is_defaultable_for_conversion() =>
{
Ok(default.into_value_default())
}
result => result,
}
}
#[inline]
pub fn to_list_or_else_with<T, F>(
&self,
default: F,
options: &DataConversionOptions,
) -> ValueResult<Vec<T>>
where
T: DataConversionTarget,
F: FnOnce() -> Vec<T>,
{
match self.to_list_with(options) {
Err(ValueError::Missing(missing))
if missing.is_defaultable_for_conversion() =>
{
Ok(default())
}
result => result,
}
}
}