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
102
103
104
105
106
107
108
109
110
111
112
113
114
|
use serde::{Deserialize, Serialize};
use thiserror::Error;
use uuid::Uuid;
use crate::op::{ChangeSubdivisions, CreateGrid, Op, OpKind};
/// An deterministically derived ID, e.g. a grid ID derived from the
/// op ID which creates it.
pub struct DerivedId {
base: String,
tag: &'static str,
index: usize,
}
impl ToString for DerivedId {
fn to_string(&self) -> String {
format!("{}:{}={}", self.base, self.tag, self.index)
}
}
trait DerivableId {
fn derive_id(&self, tag: &'static str, index: usize) -> DerivedId;
}
impl DerivableId for Uuid {
fn derive_id(&self, tag: &'static str, index: usize) -> DerivedId {
DerivedId {
base: self.to_string(),
tag,
index,
}
}
}
impl DerivableId for DerivedId {
fn derive_id(&self, tag: &'static str, index: usize) -> DerivedId {
DerivedId {
base: self.to_string(),
tag,
index,
}
}
}
impl Serialize for DerivedId {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&self.to_string())
}
}
#[derive(Default, Serialize)]
pub struct Doc {
pub(crate) grids: Vec<Grid>,
}
#[derive(Serialize)]
pub struct Grid {
pub(crate) id: DerivedId,
pub(crate) rows: Vec<Row>,
}
#[derive(Serialize)]
pub struct Row {
pub(crate) id: DerivedId,
pub(crate) cells: Vec<Cell>,
}
#[derive(Serialize)]
pub struct Cell {
pub(crate) id: DerivedId,
}
#[derive(Error, Debug)]
pub enum ApplyOpError {}
pub type ApplyOpResult = Result<(), ApplyOpError>;
impl Doc {
pub fn apply_op(&mut self, op: &Op) -> ApplyOpResult {
match &op.kind {
OpKind::CreateGrid(data) => apply_create_grid(self, &op.id, data),
OpKind::ChangeSubdivisions(data) => apply_change_subdivisions(self, data),
}
}
}
fn apply_create_grid(doc: &mut Doc, op_id: &Uuid, data: &CreateGrid) -> ApplyOpResult {
let grid_id = op_id.derive_id("grid", 0);
let rows = (0..data.rows)
.map(|row_idx| {
let row_id = grid_id.derive_id("row", row_idx);
let cells = (0..data.base_cells_per_row)
.map(|cell_idx| Cell {
id: row_id.derive_id("cell", cell_idx),
})
.collect();
Row { id: row_id, cells }
})
.collect();
doc.grids.push(Grid { id: grid_id, rows });
Ok(())
}
fn apply_change_subdivisions(doc: &mut Doc, data: &ChangeSubdivisions) -> ApplyOpResult {
todo!()
}
|