use crate::mem::InMemDicomObject;
use dicom_core::DataElement;
use dicom_parser::dataset::{DataToken, IntoTokens, IntoTokensOptions};
use std::collections::VecDeque;
pub struct InMemObjectTokens<E> {
tokens_pending: VecDeque<DataToken>,
elem_iter: E,
fused: bool,
token_options: IntoTokensOptions,
}
impl<E> InMemObjectTokens<E>
where
E: Iterator,
{
pub fn new<T>(obj: T) -> Self
where
T: IntoIterator<IntoIter = E, Item = E::Item>,
{
InMemObjectTokens {
tokens_pending: Default::default(),
elem_iter: obj.into_iter(),
fused: false,
token_options: Default::default(),
}
}
pub fn new_with_options<T>(obj: T, token_options: IntoTokensOptions) -> Self
where
T: IntoIterator<IntoIter = E, Item = E::Item>,
{
InMemObjectTokens {
tokens_pending: Default::default(),
elem_iter: obj.into_iter(),
fused: false,
token_options,
}
}
}
impl<P, I, E> Iterator for InMemObjectTokens<E>
where
E: Iterator<Item = DataElement<I, P>>,
E::Item: IntoTokens,
{
type Item = DataToken;
fn next(&mut self) -> Option<Self::Item> {
if self.fused {
return None;
}
if let Some(token) = self.tokens_pending.pop_front() {
return Some(token);
}
if let Some(elem) = self.elem_iter.next() {
self.tokens_pending = if self.token_options == Default::default() {
elem.into_tokens()
} else {
elem.into_tokens_with_options(self.token_options)
}
.collect();
self.next()
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.elem_iter.size_hint().0 * 2, None)
}
}
impl<D> IntoTokens for InMemDicomObject<D> {
type Iter = InMemObjectTokens<<InMemDicomObject<D> as IntoIterator>::IntoIter>;
fn into_tokens(self) -> Self::Iter {
InMemObjectTokens::new(self)
}
fn into_tokens_with_options(self, mut options: IntoTokensOptions) -> Self::Iter {
options.force_invalidate_sq_length |= self.charset_changed;
InMemObjectTokens::new_with_options(self, options)
}
}
impl<'a, D> IntoTokens for &'a InMemDicomObject<D>
where
D: Clone,
{
type Iter =
InMemObjectTokens<std::iter::Cloned<<&'a InMemDicomObject<D> as IntoIterator>::IntoIter>>;
fn into_tokens(self) -> Self::Iter {
self.into_tokens_with_options(Default::default())
}
fn into_tokens_with_options(self, mut options: IntoTokensOptions) -> Self::Iter {
options.force_invalidate_sq_length |= self.charset_changed;
InMemObjectTokens::new_with_options(self.into_iter().cloned(), options)
}
}