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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use super::{
    BlockChildType::BlockChildType,
    CellTrait::Cell,
    Datacell::{CellType, DataCell},
};
use serde::{Deserialize, Serialize};

#[inline]
fn is_false(v: &bool) -> bool {
    !(*v)
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct BlockCell {
    pub children: Vec<BlockChildType>,
    #[serde(skip_serializing_if = "is_false")]
    #[serde(default)]
    pub has_counter_commands: bool,
    #[serde(skip_serializing_if = "is_false")]
    #[serde(default)]
    pub has_handle_insert: bool,
}

impl BlockCell {
    pub fn new() -> BlockCell {
        BlockCell {
            children: Vec::new(),
            ..Default::default()
        }
    }

    fn insert_cell(parent: &mut DataCell, id: usize, block: &BlockCell) {
        match parent.cell_type {
            CellType::Element(ref mut el) => {
                el.children.insert(0, Self::init_cell(id, parent.id, block))
            }
            _ => (),
        }
    }

    pub fn add_cell_at_first(
        add_to: &mut DataCell,
        parent_id: usize,
        id: usize,
        block: &BlockCell,
    ) {
        if add_to.id == parent_id {
            Self::insert_cell(add_to, id, block);
            return;
        }

        match &mut add_to.cell_type {
            CellType::Element(ref mut el) => el
                .children
                .iter_mut()
                .for_each(|x| Self::add_cell_at_first(x, parent_id, id, block)),
            CellType::Root(ref mut el) => el
                .children
                .iter_mut()
                .for_each(|x| Self::add_cell_at_first(x, parent_id, id, block)),
            _ => (),
        }
    }
}

impl Cell<&BlockCell> for BlockCell {
    fn init_cell(id: usize, parent_id: usize, block: &BlockCell) -> DataCell {
        DataCell {
            id,
            parent_id,
            cell_type: CellType::Block(block.to_owned()),
        }
    }

    fn push_cell(parent: &mut DataCell, id: usize, block: &BlockCell) {
        match parent.cell_type {
            CellType::Element(ref mut el) => {
                el.children.push(Self::init_cell(id, parent.id, block))
            }
            _ => (),
        }
    }

    fn add_cell(add_to: &mut DataCell, parent_id: usize, id: usize, block: &BlockCell) {
        if add_to.id == parent_id {
            Self::push_cell(add_to, id, block);
            return;
        }

        match &mut add_to.cell_type {
            CellType::Element(ref mut el) => el
                .children
                .iter_mut()
                .for_each(|x| Self::add_cell(x, parent_id, id, block)),
            CellType::Root(ref mut el) => el
                .children
                .iter_mut()
                .for_each(|x| Self::add_cell(x, parent_id, id, block)),
            _ => (),
        }
    }
}