summaryrefslogtreecommitdiff
path: root/crdt/src/doc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crdt/src/doc.rs')
-rw-r--r--crdt/src/doc.rs101
1 files changed, 101 insertions, 0 deletions
diff --git a/crdt/src/doc.rs b/crdt/src/doc.rs
new file mode 100644
index 0000000..bbd24d0
--- /dev/null
+++ b/crdt/src/doc.rs
@@ -0,0 +1,101 @@
+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,
+ }
+ }
+}
+
+#[derive(Default)]
+pub struct Doc {
+ pub(crate) grids: Vec<Grid>,
+}
+
+pub struct Grid {
+ pub(crate) id: DerivedId,
+ pub(crate) rows: Vec<Row>,
+}
+
+pub struct Row {
+ pub(crate) id: DerivedId,
+ pub(crate) cells: Vec<Cell>,
+}
+
+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!()
+}