diff options
| author | Josh Kingsley <josh@joshkingsley.me> | 2025-11-23 19:27:57 +0200 |
|---|---|---|
| committer | Josh Kingsley <josh@joshkingsley.me> | 2025-11-23 19:27:57 +0200 |
| commit | 602145c956bb594ca0d0e10601cc4ad1a71cf70d (patch) | |
| tree | d9f9980bd2054cff5819d01379f5c1c55f8eb66d /packages/doc/src/doc.rs | |
| parent | c2a6efb1b761014a90d90373cad47a14054af40b (diff) | |
feat: integrate web and doc packages
Diffstat (limited to 'packages/doc/src/doc.rs')
| -rw-r--r-- | packages/doc/src/doc.rs | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/packages/doc/src/doc.rs b/packages/doc/src/doc.rs new file mode 100644 index 0000000..fcca1d8 --- /dev/null +++ b/packages/doc/src/doc.rs @@ -0,0 +1,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!() +} |
