1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use rui::*;

fn main() {
    rui(state(Counters::default, |counters, cx| {
        vstack((
            list(cx[counters].ids(), move |&i| {
                with_cx(move |cx| {
                    let count = bind(counters, CounterLens(i));
                    hstack((
                        format!("{}", count.get(cx)).padding(Auto),
                        button("increment", move |cx| {
                            *count.get_mut(cx) += 1;
                        })
                        .padding(Auto),
                        button("decrement", move |cx| {
                            *count.get_mut(cx) -= 1;
                        })
                        .padding(Auto),
                        button("remove", move |cx| cx[counters].remove_counter(i)).padding(Auto),
                    ))
                })
            }),
            format!("total: {}", cx[counters].sum_counters()).padding(Auto),
            button("add counter", move |cx| cx[counters].add_counter()).padding(Auto),
        ))
    }));
}

#[derive(Default, Debug)]
struct Counters {
    counters: Vec<Option<i32>>,
}

impl Counters {
    fn ids(&self) -> Vec<usize> {
        let mut ids = vec![];
        for i in 0..self.counters.len() {
            if let Some(_) = self.counters[i] {
                ids.push(i);
            }
        }
        ids
    }
    fn add_counter(&mut self) {
        self.counters.push(Some(0));
    }
    fn remove_counter(&mut self, id: usize) {
        self.counters[id] = None;
    }
    fn sum_counters(&self) -> i32 {
        let mut sum = 0;
        for c in &self.counters {
            if let Some(x) = c {
                sum += x
            }
        }
        sum
    }
}

#[derive(Copy, Clone, Debug)]
struct CounterLens(usize);

impl Lens<Counters, i32> for CounterLens {
    fn focus<'a>(&self, data: &'a Counters) -> &'a i32 {
        data.counters[self.0].as_ref().unwrap()
    }

    fn focus_mut<'a>(&self, data: &'a mut Counters) -> &'a mut i32 {
        data.counters[self.0].as_mut().unwrap()
    }
}