use super::conversion_session::ConversionSession;
use super::data_conversion_target::DataConversionTarget;
use super::data_converter::DataConverter;
use super::error::DataConversionError;
use super::error::DataListConversionError;
use super::options::ConversionLimits;
use super::options::ConversionPolicy;
#[must_use]
#[derive(Debug, Clone)]
pub struct DataConverters<I> {
sources: I,
trusted_capacity: Option<usize>,
}
impl<I> DataConverters<I>
where
I: Iterator,
{
#[inline(always)]
pub fn from_iterator(sources: I) -> Self {
Self {
sources,
trusted_capacity: None,
}
}
}
impl<I> DataConverters<I>
where
I: Iterator,
{
#[inline(always)]
pub fn to_vec<'a, T>(self) -> Result<Vec<T>, DataListConversionError>
where
I::Item: Into<DataConverter<'a>>,
T: DataConversionTarget,
{
self.to_vec_with(ConversionPolicy::default_ref(), ConversionLimits::default_ref())
}
pub fn to_vec_with<'a, T>(
self,
policy: &ConversionPolicy,
limits: &ConversionLimits,
) -> Result<Vec<T>, DataListConversionError>
where
I::Item: Into<DataConverter<'a>>,
T: DataConversionTarget,
{
let mut session = ConversionSession::new(policy, limits);
self.to_vec_in(&mut session)
}
pub fn to_vec_in<'a, T>(self, session: &mut ConversionSession<'_>) -> Result<Vec<T>, DataListConversionError>
where
I::Item: Into<DataConverter<'a>>,
T: DataConversionTarget,
{
let sources = self.sources;
let capacity = self.trusted_capacity.map_or(0, |capacity| {
capacity.min(usize::try_from(session.remaining_items()).unwrap_or(usize::MAX))
});
let mut converted = Vec::with_capacity(capacity);
for (index, source) in sources.enumerate() {
let value = match source.into().into_target_in::<T>(session) {
Ok(value) => value,
Err(source) => {
return Err(DataListConversionError::new(index, source));
}
};
converted.push(value);
}
Ok(converted)
}
#[inline(always)]
pub fn to_first<'a, T>(self) -> Result<T, DataConversionError>
where
I::Item: Into<DataConverter<'a>>,
T: DataConversionTarget,
{
self.to_first_with(ConversionPolicy::default_ref(), ConversionLimits::default_ref())
}
#[inline]
pub fn to_first_with<'a, T>(
self,
policy: &ConversionPolicy,
limits: &ConversionLimits,
) -> Result<T, DataConversionError>
where
I::Item: Into<DataConverter<'a>>,
T: DataConversionTarget,
{
let mut session = ConversionSession::new(policy, limits);
self.to_first_in(&mut session)
}
#[inline]
pub fn to_first_in<'a, T>(self, session: &mut ConversionSession<'_>) -> Result<T, DataConversionError>
where
I::Item: Into<DataConverter<'a>>,
T: DataConversionTarget,
{
let mut sources = self.sources;
match sources.next() {
Some(source) => source.into().into_target_in::<T>(session),
None => Err(DataConversionError::empty_collection(T::DATA_TYPE)),
}
}
}
impl<I> DataConverters<I>
where
I: ExactSizeIterator,
{
#[must_use]
#[inline(always)]
pub fn len(&self) -> usize {
self.sources.len()
}
#[must_use]
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.sources.len() == 0
}
}
impl<'a, V> From<&'a [V]> for DataConverters<std::slice::Iter<'a, V>> {
#[inline(always)]
fn from(values: &'a [V]) -> Self {
Self {
sources: values.iter(),
trusted_capacity: Some(values.len()),
}
}
}
impl<'a, V> From<&'a Vec<V>> for DataConverters<std::slice::Iter<'a, V>> {
#[inline(always)]
fn from(values: &'a Vec<V>) -> Self {
Self::from(values.as_slice())
}
}
impl<V> From<Vec<V>> for DataConverters<std::vec::IntoIter<V>> {
#[inline(always)]
fn from(values: Vec<V>) -> Self {
let trusted_capacity = values.len();
Self {
sources: values.into_iter(),
trusted_capacity: Some(trusted_capacity),
}
}
}