braid_core/antimatter/
json_crdt.rs1use super::crdt_trait::PrunableCrdt;
2use super::messages::Patch;
3use super::sequence_crdt::{self, SequenceElems, SequenceNode};
4use serde::{Deserialize, Serialize};
5use serde_json::{json, Value};
6use std::collections::{HashMap, HashSet};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct JsonCrdt {
10 pub id: String,
11 pub root: SequenceNode,
12 pub next_seq: u64,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct JsonPatch {
17 pub path: Vec<String>,
18 pub range: String,
19 pub content: Value,
20}
21
22impl PrunableCrdt for JsonCrdt {
23 fn apply_patch(&mut self, patch: Patch) {
24 if let Some(content_str) = patch.content.as_str() {
27 if patch.range.is_empty() {
29 self.root = SequenceNode::text(&format!("{}@{}", self.next_seq, self.id), content_str);
31 } else {
32 }
35 }
36 self.next_seq += 1;
37 }
38
39 fn prune(&mut self, version: &str) {
40 sequence_crdt::prune(&mut self.root, version);
41 }
42
43 fn get_next_seq(&self) -> u64 {
44 self.next_seq
45 }
46
47 fn generate_braid(
48 &self,
49 known_versions: &HashMap<String, bool>,
50 ) -> Vec<(String, HashMap<String, bool>, Vec<Patch>)> {
51 let visible = |v: &str| {
53 if v.is_empty() {
54 return true;
55 }
56 !known_versions.contains_key(v)
57 };
58
59 vec![(
60 self.generate_version(),
61 known_versions.clone(),
62 vec![Patch {
63 range: "0".to_string(),
64 content: json!(sequence_crdt::content(&self.root, visible)),
65 }],
66 )]
67 }
68}
69
70impl JsonCrdt {
71 pub fn new(id: &str) -> Self {
72 Self {
73 id: id.to_string(),
74 root: SequenceNode {
75 version: None,
76 elems: SequenceElems::String(String::new()),
77 next: Vec::new(),
78 deleted_by: HashSet::new(),
79 },
80 next_seq: 0,
81 }
82 }
83
84 pub fn with_content(id: &str, content: &str) -> Self {
85 let mut crdt = Self::new(id);
86 crdt.root = SequenceNode::text(&format!("0@{}", id), content);
87 crdt.next_seq = 1;
88 crdt
89 }
90
91 pub fn get_content(&self) -> String {
92 sequence_crdt::content(&self.root, |_| true)
93 }
94
95 pub fn get_length(&self) -> usize {
96 sequence_crdt::length(&self.root, |_| true)
97 }
98
99 pub fn generate_version(&self) -> String {
100 format!("{}@{}", self.next_seq, self.id)
101 }
102
103 pub fn get_frontier(&self) -> Vec<String> {
104 let mut versions = HashSet::new();
106 let mut stack = vec![&self.root];
107 while let Some(node) = stack.pop() {
108 if let Some(v) = &node.version {
109 versions.insert(v.clone());
110 }
111 for child in &node.next {
112 stack.push(child);
113 }
114 }
115 versions.into_iter().collect()
116 }
117}