diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..693373e --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "rustlog" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..ca814f4 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "rustlog" +version = "0.1.0" +edition = "2024" + +[dependencies] + +[[bin]] +name = "rustlog" +path = "main.rs" diff --git a/blocktree.rs b/blocktree.rs new file mode 100644 index 0000000..3be2920 --- /dev/null +++ b/blocktree.rs @@ -0,0 +1,88 @@ + +use std::collections::HashMap; + +#[derive(Debug)] +pub struct NoteBlock { + // IDs are int64 as this is the datatype of rowids in sqlite + id: i64, + first_child_id: Option, + next_sibling_id: Option, + + content: String +} + +impl NoteBlock { + pub fn new(id: i64, first_child_id: Option, next_sibling_id: Option, content: String) -> Self { + Self {id, first_child_id, next_sibling_id, content} + } +} + +#[derive(Debug)] +struct BlockTreeNode { + // a tree of nodes, where each node refers to its block by id. + // the id is used as the key in a page's block table. + block_id: i64, + block_level: Option, + first_child_node: Option>, + next_sibling_node: Option> +} + +impl BlockTreeNode { + pub fn new(block_id: i64) -> Self { + BlockTreeNode { + block_id, + block_level: None, + first_child_node: None, + next_sibling_node: None + } + } +} + +#[derive(Debug)] +pub struct NotePage { + title: String, + id: i64, + block_tree_root: BlockTreeNode, + + block_table: HashMap +} + +impl NotePage { + pub fn new(title: String, id: i64, root_block: NoteBlock) -> Self { + let mut new_page = Self { + title, + id, + block_tree_root: BlockTreeNode::new(root_block.id), + block_table: HashMap::new() + }; + new_page.block_tree_root.block_level = Some(0); + new_page.block_table.insert(root_block.id, root_block); + new_page + } + + pub fn insert(self: &mut Self, block: NoteBlock) { + self.block_table.insert(block.id, block); + } + + pub fn build_tree(self: &mut Self) { + let mut node_stack = Vec::new(); + node_stack.push(&mut self.block_tree_root); + while !node_stack.is_empty() { + println!("{:?}", node_stack); + let current_node = node_stack.pop().unwrap(); + let current_block = self.block_table.get(¤t_node.block_id).unwrap(); + if let Some(next_sibling_id) = current_block.next_sibling_id { + let mut sibling_node = BlockTreeNode::new(next_sibling_id); + sibling_node.block_level = current_node.block_level; + current_node.next_sibling_node = Some(Box::new(sibling_node)); + node_stack.push(current_node.next_sibling_node.as_mut().unwrap()); + } + if let Some(first_child_id) = current_block.first_child_id { + let mut child_node = BlockTreeNode::new(first_child_id); + child_node.block_level = Some(current_node.block_level.unwrap() + 1); + current_node.first_child_node = Some(Box::new(child_node)); + node_stack.push(current_node.first_child_node.as_mut().unwrap()); + } + } + } +} diff --git a/main.rs b/main.rs new file mode 100644 index 0000000..20e32da --- /dev/null +++ b/main.rs @@ -0,0 +1,20 @@ +mod blocktree; + +use crate::blocktree::{NoteBlock, NotePage}; + +fn main() { + let root_block = NoteBlock::new(0,Some(1),Some(2),String::from("hello")); + let mut page = NotePage::new(String::from("page 1"), 0, root_block); + let new_block = NoteBlock::new(1,None,None, String::from("world")); + page.insert(new_block); + let new_block = NoteBlock::new(2,Some(3),None, String::from("world")); + page.insert(new_block); + let new_block = NoteBlock::new(3,Some(4),None, String::from("world")); + page.insert(new_block); + let new_block = NoteBlock::new(4,None,None, String::from("world")); + page.insert(new_block); + page.build_tree(); + + println!("{:?}", page); +// println!("{:?}", page.block_tree_root.first_child_node) +}