summaryrefslogtreecommitdiff
path: root/packages/doc/src/doc.rs
diff options
context:
space:
mode:
authorJosh Kingsley <josh@joshkingsley.me>2025-11-23 19:27:57 +0200
committerJosh Kingsley <josh@joshkingsley.me>2025-11-23 19:27:57 +0200
commit602145c956bb594ca0d0e10601cc4ad1a71cf70d (patch)
treed9f9980bd2054cff5819d01379f5c1c55f8eb66d /packages/doc/src/doc.rs
parentc2a6efb1b761014a90d90373cad47a14054af40b (diff)
feat: integrate web and doc packages
Diffstat (limited to 'packages/doc/src/doc.rs')
-rw-r--r--packages/doc/src/doc.rs114
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!()
+}