1use crate::mem::InMemDicomObject;
3use dicom_core::DataElement;
4use dicom_parser::dataset::{DataToken, IntoTokens, IntoTokensOptions};
5use std::collections::VecDeque;
6
7pub struct InMemObjectTokens<E> {
9 tokens_pending: VecDeque<DataToken>,
11 elem_iter: E,
13 fused: bool,
15 token_options: IntoTokensOptions,
17}
18
19impl<E> InMemObjectTokens<E>
20where
21 E: Iterator,
22{
23 pub fn new<T>(obj: T) -> Self
24 where
25 T: IntoIterator<IntoIter = E, Item = E::Item>,
26 {
27 InMemObjectTokens {
28 tokens_pending: Default::default(),
29 elem_iter: obj.into_iter(),
30 fused: false,
31 token_options: Default::default(),
32 }
33 }
34
35 pub fn new_with_options<T>(obj: T, token_options: IntoTokensOptions) -> Self
36 where
37 T: IntoIterator<IntoIter = E, Item = E::Item>,
38 {
39 InMemObjectTokens {
40 tokens_pending: Default::default(),
41 elem_iter: obj.into_iter(),
42 fused: false,
43 token_options,
44 }
45 }
46}
47
48impl<P, I, E> Iterator for InMemObjectTokens<E>
49where
50 E: Iterator<Item = DataElement<I, P>>,
51 E::Item: IntoTokens,
52{
53 type Item = DataToken;
54
55 fn next(&mut self) -> Option<Self::Item> {
56 if self.fused {
57 return None;
58 }
59
60 if let Some(token) = self.tokens_pending.pop_front() {
62 return Some(token);
63 }
64
65 if let Some(elem) = self.elem_iter.next() {
67 self.tokens_pending = if self.token_options == Default::default() {
68 elem.into_tokens()
69 } else {
70 elem.into_tokens_with_options(self.token_options)
71 }
72 .collect();
73
74 self.next()
75 } else {
76 None
78 }
79 }
80
81 fn size_hint(&self) -> (usize, Option<usize>) {
82 (self.elem_iter.size_hint().0 * 2, None)
85 }
86}
87
88impl<D> IntoTokens for InMemDicomObject<D> {
89 type Iter = InMemObjectTokens<<InMemDicomObject<D> as IntoIterator>::IntoIter>;
90
91 fn into_tokens(self) -> Self::Iter {
92 InMemObjectTokens::new(self)
93 }
94
95 fn into_tokens_with_options(self, mut options: IntoTokensOptions) -> Self::Iter {
96 options.force_invalidate_sq_length |= self.charset_changed;
98 InMemObjectTokens::new_with_options(self, options)
99 }
100}
101
102impl<'a, D> IntoTokens for &'a InMemDicomObject<D>
103where
104 D: Clone,
105{
106 type Iter =
107 InMemObjectTokens<std::iter::Cloned<<&'a InMemDicomObject<D> as IntoIterator>::IntoIter>>;
108
109 fn into_tokens(self) -> Self::Iter {
110 self.into_tokens_with_options(Default::default())
111 }
112
113 fn into_tokens_with_options(self, mut options: IntoTokensOptions) -> Self::Iter {
114 options.force_invalidate_sq_length |= self.charset_changed;
115
116 InMemObjectTokens::new_with_options(self.into_iter().cloned(), options)
117 }
118}