1#![no_std]
2extern crate alloc;
3use alloc::vec;
4use alloc::vec::Vec;
5
6pub fn union<A: Eq>(mut b: impl Iterator<Item: Iterator<Item = A>>) -> Union<A> {
7 let Some(a) = b.next() else {
8 return Union {
9 vals: vec![],
10 poss: vec![],
11 };
12 };
13 let mut vals = a.collect::<Vec<_>>();
14 let pos1s = vals.iter().enumerate().map(|a| a.0).collect();
15 let mut poss = vec![pos1s];
16 for b in b {
17 let mut pos2s: Vec<usize> = vec![];
18 for b in b {
19 match vals
20 .iter()
21 .enumerate()
22 .filter(|(i, a)| !pos2s.contains(&i))
23 .find(|(i, x)| **x == b)
24 {
25 Some(c) => pos2s.push(c.0),
26 None => {
27 pos2s.push(vals.len());
28 vals.push(b)
29 }
30 }
31 }
32 poss.push(pos2s);
33 }
34 Union { vals, poss }
35}
36pub struct Union<A> {
37 pub vals: Vec<A>,
38 pub poss: Vec<Vec<usize>>,
39}
40impl<A> Union<A> {
41 pub fn create<B, E>(
42 &self,
43 i: usize,
44 default: impl FnMut(&A) -> Result<B, E>,
45 vals: impl Iterator<Item = Result<B, E>>,
46 ) -> Result<Vec<B>, E> {
47 let mut bs: Vec<B> = self.vals.iter().map(default).collect::<Result<_, E>>()?;
48 for (j, b) in self.poss[i].iter().cloned().zip(vals) {
49 bs[j] = b?;
50 }
51 return Ok(bs);
52 }
53}