1use std::{cell::RefCell, fmt, rc::Rc};
13
14use crate::{value::LoadStore, TypeSet, TypedValue};
15
16type BoxedIter<T> = std::iter::Peekable<Box<dyn Iterator<Item = TypedValue<T>>>>;
21
22pub struct SomniIterator<T: TypeSet> {
30 inner: Rc<RefCell<BoxedIter<T>>>,
31}
32
33impl<T: TypeSet> SomniIterator<T> {
34 pub fn new<I>(iter: I) -> Self
36 where
37 I: IntoIterator<Item = TypedValue<T>> + 'static,
38 {
39 let boxed: Box<dyn Iterator<Item = TypedValue<T>>> = Box::new(iter.into_iter());
40 Self {
41 inner: Rc::new(RefCell::new(boxed.peekable())),
42 }
43 }
44
45 #[doc(hidden)]
47 pub fn has_next(&self) -> bool {
48 self.inner.borrow_mut().peek().is_some()
49 }
50
51 #[doc(hidden)]
53 pub fn next_value(&self) -> Option<TypedValue<T>> {
54 self.inner.borrow_mut().next()
55 }
56}
57
58impl<T: TypeSet> Clone for SomniIterator<T> {
59 fn clone(&self) -> Self {
60 Self {
61 inner: self.inner.clone(),
62 }
63 }
64}
65
66impl<T: TypeSet> fmt::Debug for SomniIterator<T> {
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 f.write_str("<iter>")
69 }
70}
71
72impl<T: TypeSet> PartialEq for SomniIterator<T> {
73 fn eq(&self, other: &Self) -> bool {
74 Rc::ptr_eq(&self.inner, &other.inner)
75 }
76}
77
78impl<T> LoadStore<WithIterator<T>> for SomniIterator<T>
79where
80 T: TypeSet,
81 WithIterator<T>: TypeSet<Iterator = SomniIterator<T>>,
82{
83 type Output<'s> = Self;
84
85 fn load<'s>(
86 _ctx: &'s WithIterator<T>,
87 typed: &'s TypedValue<WithIterator<T>>,
88 ) -> Option<Self::Output<'s>> {
89 if let TypedValue::Iter(iter) = typed {
90 Some(iter.clone())
91 } else {
92 None
93 }
94 }
95
96 fn store(&self, _ctx: &mut WithIterator<T>) -> TypedValue<WithIterator<T>> {
97 TypedValue::Iter(self.clone())
98 }
99}
100
101pub struct WithIterator<T: TypeSet> {
108 pub inner: T,
110}
111
112impl<T: TypeSet> Default for WithIterator<T> {
113 fn default() -> Self {
114 Self {
115 inner: T::default(),
116 }
117 }
118}
119
120impl<T: TypeSet> fmt::Debug for WithIterator<T> {
121 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122 f.debug_struct("WithIterator")
123 .field("inner", &self.inner)
124 .finish()
125 }
126}
127
128#[macro_export]
137macro_rules! impl_with_iterator {
138 ($inner:ty) => {
139 impl $crate::TypeSet for $crate::WithIterator<$inner> {
140 type Parser = <$inner as $crate::TypeSet>::Parser;
141 type Integer = <$inner as $crate::TypeSet>::Integer;
142 type SignedInteger = <$inner as $crate::TypeSet>::SignedInteger;
143 type Float = <$inner as $crate::TypeSet>::Float;
144 type String = <$inner as $crate::TypeSet>::String;
145 type Iterator = $crate::SomniIterator<$inner>;
146
147 fn to_signed(v: Self::Integer) -> Result<Self::SignedInteger, $crate::OperatorError> {
148 <$inner as $crate::TypeSet>::to_signed(v)
149 }
150
151 fn to_usize(v: Self::Integer) -> Result<usize, $crate::OperatorError> {
152 <$inner as $crate::TypeSet>::to_usize(v)
153 }
154
155 fn int_from_usize(v: usize) -> Self::Integer {
156 <$inner as $crate::TypeSet>::int_from_usize(v)
157 }
158
159 fn load_string<'s>(&'s self, str: &'s Self::String) -> &'s str {
160 self.inner.load_string(str)
161 }
162
163 fn store_string(&mut self, str: &str) -> Self::String {
164 self.inner.store_string(str)
165 }
166
167 fn iter_has_next(&self, iter: &Self::Iterator) -> bool {
168 iter.has_next()
169 }
170
171 fn iter_next(&self, iter: &Self::Iterator) -> Option<$crate::TypedValue<Self>> {
172 iter.next_value().map(|value| match value {
173 TypedValue::Void => TypedValue::Void,
174 TypedValue::MaybeSignedInt(v) => TypedValue::MaybeSignedInt(v),
175 TypedValue::Int(v) => TypedValue::Int(v),
176 TypedValue::SignedInt(v) => TypedValue::SignedInt(v),
177 TypedValue::Float(v) => TypedValue::Float(v),
178 TypedValue::Bool(v) => TypedValue::Bool(v),
179 TypedValue::String(v) => TypedValue::String(v),
180 TypedValue::Iter(never) => match never {},
181 })
182 }
183 }
184 };
185}
186
187impl_with_iterator!(crate::DefaultTypeSet);
188impl_with_iterator!(crate::TypeSet32);
189impl_with_iterator!(crate::TypeSet128);