unobtanium_segmenter/
subdivision_map.rs1use std::marker::PhantomData;
2use std::mem;
3
4pub enum UseOrSubdivide<T, I: Iterator<Item = T>> {
8 Empty,
10
11 Use(T),
13
14 Subdivide(I),
18}
19
20impl<T, I: Iterator<Item = T>> Iterator for UseOrSubdivide<T, I> {
21 type Item = T;
22
23 fn next(&mut self) -> Option<Self::Item> {
24 match self {
25 Self::Empty => {
26 return None;
27 }
28 Self::Use(_) => {
29 let taken_use_or_subdivide = mem::replace(self, UseOrSubdivide::Empty);
30 match taken_use_or_subdivide {
31 Self::Use(data) => {
32 return Some(data);
33 }
34 _ => unreachable!("this code only runs when UseOrSubdivide::Use"),
35 }
36 }
37 Self::Subdivide(iter) => {
38 return iter.next();
39 }
40 }
41 }
42}
43
44pub struct SubdivisionMap<
48 'i,
49 T: 'i,
50 I: Iterator<Item = T> + 'i,
51 R: Iterator<Item = T> + 'i,
52 F: Fn(T) -> UseOrSubdivide<T, R>,
53> {
54 _marker: PhantomData<&'i ()>,
55 iter: I,
56 buffer: Option<R>,
57 callback: F,
58}
59
60impl<
61 'i,
62 T,
63 I: Iterator<Item = T> + 'i,
64 R: Iterator<Item = T> + 'i,
65 F: Fn(T) -> UseOrSubdivide<T, R>,
66 > SubdivisionMap<'i, T, I, R, F>
67{
68 pub fn new(iter: I, callback: F) -> Self {
71 Self {
72 _marker: PhantomData,
73 iter,
74 callback,
75 buffer: None,
76 }
77 }
78}
79
80impl<
81 'i,
82 T,
83 I: Iterator<Item = T> + 'i,
84 R: Iterator<Item = T> + 'i,
85 F: Fn(T) -> UseOrSubdivide<T, R>,
86 > Iterator for SubdivisionMap<'i, T, I, R, F>
87{
88 type Item = I::Item;
89
90 fn next(&mut self) -> Option<Self::Item> {
91 loop {
92 if let Some(buffer_iter) = &mut self.buffer {
93 if let Some(item) = buffer_iter.next() {
94 return Some(item);
95 }
96 self.buffer = None;
97 }
98 if let Some(raw_item) = self.iter.next() {
99 match (self.callback)(raw_item) {
100 UseOrSubdivide::Empty => return None,
101 UseOrSubdivide::Use(item) => return Some(item),
102 UseOrSubdivide::Subdivide(list) => {
103 self.buffer = Some(list.into_iter());
104 }
106 }
107 } else {
108 return None;
109 }
110 }
111 }
112}