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
mod cell;
mod sheet_range;
mod sts_range;
use logisheets_base::NameId;
use super::graph::Graph;
pub type FormulaId = cell::FormulaId;
pub type SheetRangeVertex = sheet_range::SheetRangeVertex;
pub type MutReferenceVertex = sheet_range::MutReferenceVertex;
pub type StsRangeVertex = sts_range::StsRangeVertex;
pub type MutRowRange = sheet_range::MutRowRange;
pub type MutColRange = sheet_range::MutColRange;
pub type MutAddrRange = sheet_range::AddrRange;
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub enum Vertex {
Cell(FormulaId),
SheetRange(SheetRangeVertex),
StsRange(StsRangeVertex),
External,
Name(NameId),
}
impl PartialOrd for Vertex {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Vertex {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
let to_u32 = |v: &Self| -> u32 {
match v {
Vertex::Cell(_) => 1,
Vertex::SheetRange(_) => 2,
Vertex::StsRange(_) => 3,
Vertex::External => 4,
Vertex::Name(_) => 5,
}
};
to_u32(self).cmp(&to_u32(other))
}
}
impl Graph<Vertex> {
pub fn merge_vertex(self, arg1: &SheetRangeVertex, arg2: &SheetRangeVertex) -> Self {
let v1 = Vertex::SheetRange(arg1.clone());
let v2 = Vertex::SheetRange(arg2.clone());
self.convert_vertex(&v1, v2)
}
pub fn remove_sheetrange_vertex(self, arg: &SheetRangeVertex) -> Self {
let v = Vertex::SheetRange(arg.clone());
self.delete_vertex(&v)
}
pub fn remove_cell_vertex(self, fid: &FormulaId) -> Self {
let v = Vertex::Cell(fid.clone());
self.delete_vertex(&v)
}
pub fn erase_vertex(self, v: &Vertex) -> Self {
let new_rdeps = {
if let Some(deps) = self.deps.get(&v) {
deps.iter().fold(self.rdeps, |prev, d| {
if let Some(rs) = prev.get(d) {
prev.update(d.clone(), rs.clone().without(&v))
} else {
prev
}
})
} else {
self.rdeps
}
};
let new_deps = self.deps.without(&v);
Graph {
deps: new_deps,
rdeps: new_rdeps,
}
}
}