diff options
Diffstat (limited to 'crdt/src/doc.rs')
| -rw-r--r-- | crdt/src/doc.rs | 101 |
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!() +} |
