use std::cell::Cell;
mod inner {
use std::cell::Cell;
pub struct Inner<'a, T: 'a>(pub &'a Cell<Option<T>>);
impl<'a, T: Copy> Iterator for Inner<'a, T> {
type Item = T;
fn next(&mut self) -> Option<T> {
self.0.get()
}
}
}
pub struct Feedback<T> {
t: Cell<Option<T>>,
}
pub struct FeedbackIter<'a, I, T: 'a> {
iter: I,
inner: &'a Cell<Option<T>>,
}
pub fn feedback<T>(initial: T) -> Feedback<T>
where T: Copy
{
Feedback {
t: Cell::new(Some(initial)),
}
}
impl<T> Feedback<T> where T: Copy
{
pub fn feed<'a, F, I>(&'a mut self, inner: F) -> FeedbackIter<'a, I, T>
where F: FnOnce(inner::Inner<'a, T>) -> I,
T: Copy
{
FeedbackIter {
iter: inner(inner::Inner(&self.t)),
inner: &self.t,
}
}
}
impl<'a, I, T> Iterator for FeedbackIter<'a, I, T>
where I: Iterator<Item = T>,
T: Copy
{
type Item = T;
fn next(&mut self) -> Option<T> {
if let Some(v) = self.inner.get() {
self.inner.set(self.iter.next());
Some(v)
} else {
None
}
}
}