Skip to content

Commit

Permalink
Introduce document module
Browse files Browse the repository at this point in the history
This module holds the automerge `AutoCommit` document now with all the
necessary methods around it we need.

Additionally this commit prepares the use of a hard-coded byte
representation to construct the document. This will allow us to
independently create documents across peers as all peers will create the
_same_ document schema whenever they do it. More about it here:

<https://automerge.org/docs/cookbook/modeling-data/#setting-up-an-initial-document-structure>
  • Loading branch information
adzialocha committed Dec 9, 2024
1 parent 9f78995 commit ac6849e
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 3 deletions.
82 changes: 82 additions & 0 deletions src/document.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use std::fmt;

use anyhow::Result;
use automerge::{AutoCommit, AutoSerde, Patch};

const DOCUMENT_OBJ_ID: &str = "doc";

const DOCUMENT_SCHEMA: [u8] = [1, 2, 3];

#[derive(Debug)]
pub struct Document {
doc: RefCell<AutoCommit>,
}

impl Document {
pub fn new() -> Self {
let doc = AutoCommit::new();
doc.put_object(automerge::ROOT, DOCUMENT_OBJ_ID, ObjType::Text)
.expect("inserting text object '{DOCUMENT_OBJ_ID}' at root");
Self {
doc: RefCell::new(doc),
}
}

pub fn from_bytes(bytes: &[u8]) -> Self {
let doc = AutoCommit::load(bytes).expect("load automerge document from bytes");
Self {
doc: RefCell::new(doc),
}
}

pub fn update(&mut self, position: i32, del: i32, text: &str) -> Result<()> {
let mut doc = self.doc.borrow_mut();
doc.splice_text(&root, position as usize, del as isize, text)?;
// Move the diff pointer forward to current position
doc.update_diff_cursor();
Ok(())
}

pub fn load_incremental(&mut self, bytes: &[u8]) -> Result<()> {
let mut doc = self.doc.borrow_mut();
doc.load_incremental(&bytes)?;
Ok(())
}

pub fn diff_incremental(&mut self) -> Vec<Patch> {
let mut doc = self.doc.borrow_mut();
doc.diff_incremental()
}

pub fn text(&self) -> String {
let doc = self.doc.borrow();
let obj = doc.get(automerge::ROOT, DOCUMENT_OBJ_ID);
doc.text(&obj)
.expect("text to be given in automerge document")
}

pub fn save(&mut self) -> Vec<u8> {
let mut doc = self.doc.borrow_mut();
doc.save()
}

pub fn save_incremental(&mut self) -> Vec<u8> {
let mut doc = self.doc.borrow_mut();
doc.save_incremental()
}
}

impl Default for Document {
fn default() -> Self {
Self::from_bytes(&DOCUMENT_SCHEMA)
}
}

impl fmt::Debug for Document {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut doc = self.doc.borrow();
let json = serde_json::to_string_pretty(&AutoSerde::from(doc))
.expect("serialize automerge document to JSON");
write!(f, "{}", json)
}
}
7 changes: 4 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,20 @@

mod application;
mod config;
mod document;
mod network;
mod operation;
mod window;
mod textbuffer;
mod window;

use self::application::AardvarkApplication;
use self::window::AardvarkWindow;
use self::textbuffer::AardvarkTextBuffer;
use self::window::AardvarkWindow;

use config::{GETTEXT_PACKAGE, LOCALEDIR, PKGDATADIR};
use gettextrs::{bind_textdomain_codeset, bindtextdomain, textdomain};
use gtk::{gio, glib};
use gtk::prelude::*;
use gtk::{gio, glib};

fn main() -> glib::ExitCode {
// Set up gettext translations
Expand Down

0 comments on commit ac6849e

Please sign in to comment.