Browse Source

feat: document model in rust

Vincent Chan 2 years ago
parent
commit
7d404ff0da

+ 7 - 0
shared-lib/Cargo.lock

@@ -741,6 +741,12 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "indextree"
+version = "4.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42b4b46b3311ebd8e5cd44f6b03b36e0f48a70552cf6b036afcebc5626794066"
+
 [[package]]
 name = "instant"
 version = "0.1.12"
@@ -809,6 +815,7 @@ dependencies = [
  "bytes",
  "dashmap",
  "derive_more",
+ "indextree",
  "lazy_static",
  "log",
  "md5",

+ 1 - 0
shared-lib/lib-ot/Cargo.toml

@@ -24,6 +24,7 @@ lazy_static = "1.4.0"
 strum = "0.21"
 strum_macros = "0.21"
 bytes = "1.0"
+indextree = "4.4.0"
 
 
 [features]

+ 9 - 0
shared-lib/lib-ot/src/core/document/attributes.rs

@@ -0,0 +1,9 @@
+use std::collections::HashMap;
+
+pub struct NodeAttributes(HashMap<String, Option<String>>);
+
+impl NodeAttributes {
+    pub fn new() -> NodeAttributes {
+        NodeAttributes(HashMap::new())
+    }
+}

+ 52 - 0
shared-lib/lib-ot/src/core/document/document.rs

@@ -0,0 +1,52 @@
+use crate::core::document::position::Position;
+use crate::core::NodeData;
+use indextree::{Arena, NodeId};
+
+pub struct DocumentTree {
+    arena: Arena<NodeData>,
+    root: NodeId,
+}
+
+impl DocumentTree {
+    pub fn new() -> DocumentTree {
+        let mut arena = Arena::new();
+        let root = arena.new_node(NodeData::new("root".into()));
+        DocumentTree {
+            arena: Arena::new(),
+            root,
+        }
+    }
+
+    pub fn node_at_path(&self, position: &Position) -> Option<NodeId> {
+        if position.is_empty() {
+            return None;
+        }
+
+        let mut iterate_node = self.root;
+
+        for id in &position.0 {
+            let child = self.child_at_index_of_path(iterate_node, id.clone());
+            iterate_node = match child {
+                Some(node) => node,
+                None => return None,
+            };
+        }
+
+        Some(iterate_node)
+    }
+
+    fn child_at_index_of_path(&self, at_node: NodeId, index: usize) -> Option<NodeId> {
+        let children = at_node.children(&self.arena);
+
+        let mut counter = 0;
+        for child in children {
+            if counter == index {
+                return Some(child);
+            }
+
+            counter += 1;
+        }
+
+        None
+    }
+}

+ 8 - 0
shared-lib/lib-ot/src/core/document/mod.rs

@@ -0,0 +1,8 @@
+mod attributes;
+mod document;
+mod node;
+mod position;
+
+pub use attributes::*;
+pub use document::*;
+pub use node::*;

+ 15 - 0
shared-lib/lib-ot/src/core/document/node.rs

@@ -0,0 +1,15 @@
+use crate::core::NodeAttributes;
+
+pub struct NodeData {
+    pub node_type: String,
+    pub attributes: NodeAttributes,
+}
+
+impl NodeData {
+    pub fn new(node_type: &str) -> NodeData {
+        NodeData {
+            node_type: node_type.into(),
+            attributes: NodeAttributes::new(),
+        }
+    }
+}

+ 7 - 0
shared-lib/lib-ot/src/core/document/position.rs

@@ -0,0 +1,7 @@
+pub struct Position(pub Vec<usize>);
+
+impl Position {
+    pub fn is_empty(&self) -> bool {
+        self.0.is_empty()
+    }
+}

+ 2 - 0
shared-lib/lib-ot/src/core/mod.rs

@@ -1,9 +1,11 @@
 mod delta;
+mod document;
 mod interval;
 mod operation;
 mod ot_str;
 
 pub use delta::*;
+pub use document::*;
 pub use interval::*;
 pub use operation::*;
 pub use ot_str::*;

+ 6 - 0
shared-lib/lib-ot/tests/main.rs

@@ -1 +1,7 @@
+use lib_ot::core::DocumentTree;
 
+#[test]
+fn main() {
+    // Create a new arena
+    let _document = DocumentTree::new();
+}