use qubit_datatype::DataType;
use crate::IntoValueDefault;
use crate::value_error::{
ValueError,
ValueResult,
};
use super::multi_values::MultiValues;
use super::multi_values_add_arg::MultiValuesAddArg;
use super::multi_values_adder::MultiValuesAdder;
use super::multi_values_constructor_arg::MultiValuesConstructorArg;
use super::multi_values_first_getter::MultiValuesFirstGetter;
use super::multi_values_getter::MultiValuesGetter;
use super::multi_values_multi_adder::MultiValuesMultiAdder;
use super::multi_values_set_arg::MultiValuesSetArg;
use super::multi_values_setter::MultiValuesSetter;
use super::multi_values_setter_slice::MultiValuesSetterSlice;
use super::multi_values_single_setter::MultiValuesSingleSetter;
macro_rules! multi_values_data_type_match {
($value:expr; $(($variant:ident, $type:ty, $data_type:expr)),+ $(,)?) => {
match $value {
MultiValues::Empty(dt) => *dt,
$(MultiValues::$variant(_) => $data_type,)+
}
};
}
macro_rules! multi_values_count_match {
($value:expr; $(($variant:ident, $type:ty, $data_type:expr)),+ $(,)?) => {
match $value {
MultiValues::Empty(_) => 0,
$(MultiValues::$variant(values) => values.len(),)+
}
};
}
macro_rules! multi_values_clear_match {
($value:expr; $(($variant:ident, $type:ty, $data_type:expr)),+ $(,)?) => {
match $value {
MultiValues::Empty(_) => {}
$(MultiValues::$variant(values) => values.clear(),)+
}
};
}
impl MultiValues {
#[inline]
pub fn new<'a, S>(values: S) -> Self
where
S: MultiValuesConstructorArg<'a>,
{
values.into_multi_values()
}
#[inline]
pub fn get<T>(&self) -> ValueResult<Vec<T>>
where
Self: MultiValuesGetter<T>,
{
<Self as MultiValuesGetter<T>>::get_values(self)
}
#[inline]
pub fn get_or<T>(&self, default: impl IntoValueDefault<Vec<T>>) -> ValueResult<Vec<T>>
where
Self: MultiValuesGetter<T>,
{
let values = self.get()?;
if values.is_empty() {
Ok(default.into_value_default())
} else {
Ok(values)
}
}
#[inline]
pub fn get_first<T>(&self) -> ValueResult<T>
where
Self: MultiValuesFirstGetter<T>,
{
<Self as MultiValuesFirstGetter<T>>::get_first_value(self)
}
#[inline]
pub fn get_first_or<T>(&self, default: impl IntoValueDefault<T>) -> ValueResult<T>
where
Self: MultiValuesFirstGetter<T>,
{
match self.get_first() {
Err(ValueError::NoValue) => Ok(default.into_value_default()),
result => result,
}
}
#[inline]
pub fn set<'a, S>(&mut self, values: S) -> ValueResult<()>
where
S: MultiValuesSetArg<'a>,
Self: MultiValuesSetter<S::Item>
+ MultiValuesSetterSlice<S::Item>
+ MultiValuesSingleSetter<S::Item>,
{
values.apply(self)
}
#[inline]
pub fn add<'a, S>(&mut self, values: S) -> ValueResult<()>
where
S: MultiValuesAddArg<'a>,
Self: MultiValuesAdder<S::Item> + MultiValuesMultiAdder<S::Item>,
{
values.apply_add(self)
}
#[inline]
pub fn data_type(&self) -> DataType {
for_each_multi_value_type!(multi_values_data_type_match, self)
}
#[inline]
pub fn count(&self) -> usize {
for_each_multi_value_type!(multi_values_count_match, self)
}
#[inline]
pub fn is_empty(&self) -> bool {
self.count() == 0
}
#[inline]
pub fn clear(&mut self) {
for_each_multi_value_type!(multi_values_clear_match, self)
}
#[inline]
pub fn set_type(&mut self, data_type: DataType) {
if self.data_type() != data_type {
*self = MultiValues::Empty(data_type);
}
}
}