feat: add decode state and loro to_json

This commit is contained in:
leeeon233 2022-11-23 21:08:21 +08:00 committed by Zixuan Chen
parent 0c3c96c7fd
commit be0270140b
9 changed files with 85 additions and 0 deletions

View file

@ -39,11 +39,14 @@ fn main() {
0,
start.elapsed().as_millis()
);
let json1 = loro.to_json();
let start = Instant::now();
let loro = LoroCore::decode_snapshot(&buf, None, Configure::default());
println!("decode used {}ms", start.elapsed().as_millis());
let buf2 = loro.encode_snapshot();
assert_eq!(buf, buf2);
let json2 = loro.to_json();
assert_eq!(json1, json2);
let mut last = 100;
let mut count = 0;
let mut max_count = 0;

View file

@ -270,6 +270,16 @@ impl ListContainer {
}
}
}
#[cfg(feature = "json")]
pub fn to_json(&self) -> serde_json::Value {
let mut arr = Vec::new();
for i in 0..self.values_len() {
let v = self.get(i).unwrap();
arr.push(v.to_json_value());
}
serde_json::Value::Array(arr)
}
}
impl Container for ListContainer {

View file

@ -216,6 +216,16 @@ impl MapContainer {
.get(key)
.map(|v| self.pool.slice(&(v.value..v.value + 1)).first().unwrap())
}
#[cfg(feature = "json")]
pub fn to_json(&self) -> serde_json::Value {
let mut map = serde_json::Map::new();
for (k, v) in self.state.iter() {
let value = self.pool.slice(&(v.value..v.value + 1)).first().unwrap();
map.insert(k.to_string(), value.to_json_value());
}
serde_json::Value::Object(map)
}
}
fn calculate_map_diff(

View file

@ -269,6 +269,22 @@ impl ContainerRegistry {
}
}
#[cfg(feature = "json")]
pub fn to_json(&self) -> serde_json::Value {
let mut map = serde_json::Map::new();
for ContainerAndId { container, id } in self.containers.iter() {
let container = container.lock().unwrap();
let json = match container.deref() {
ContainerInstance::Map(x) => x.to_json(),
ContainerInstance::Text(x) => x.to_json(),
ContainerInstance::Dyn(_) => unreachable!("registry to json"),
ContainerInstance::List(x) => x.to_json(),
};
map.insert(serde_json::to_string(id).unwrap(), json);
}
serde_json::Value::Object(map)
}
pub(crate) fn export(&self) -> (&FxHashMap<ContainerID, ContainerIdx>, Vec<ContainerID>) {
(
&self.container_to_idx,

View file

@ -163,6 +163,15 @@ impl TextContainer {
);
self.state.debug_inspect();
}
#[cfg(feature = "json")]
pub fn to_json(&self) -> serde_json::Value {
let mut s = String::new();
for slice in self.state.iter() {
s.push_str(&self.raw_str.get_str(&slice.as_ref().0));
}
serde_json::Value::String(s)
}
}
impl Container for TextContainer {

View file

@ -295,10 +295,13 @@ pub fn test_single_client_encode(mut actions: Vec<Action>) {
}
}
let encode_bytes = store.encode_snapshot();
let json1 = store.to_json();
let store2 =
LoroCore::decode_snapshot(&encode_bytes, None, crate::configure::Configure::default());
let encode_bytes2 = store2.encode_snapshot();
let json2 = store2.to_json();
assert_eq!(encode_bytes, encode_bytes2);
assert_eq!(json1, json2);
}
pub fn minify_error<T, F, N>(site_num: u8, actions: Vec<T>, f: F, normalize: N)

View file

@ -363,6 +363,11 @@ impl LogStore {
self.hierarchy = hierarchy;
result
}
#[cfg(feature = "json")]
pub fn to_json(&self) -> String {
self.reg.to_json().to_string()
}
}
impl Dag for LogStore {

View file

@ -100,4 +100,9 @@ impl LoroCore {
pub fn debug_inspect(&self) {
self.log_store.write().unwrap().debug_inspect();
}
#[cfg(feature = "json")]
pub fn to_json(&self) -> String {
self.log_store.read().unwrap().to_json()
}
}

View file

@ -61,6 +61,30 @@ impl LoroValue {
serde_json::to_string(self).unwrap()
}
#[cfg(feature = "json")]
pub fn to_json_value(&self) -> serde_json::Value {
match self {
LoroValue::Null => serde_json::Value::Null,
LoroValue::Bool(b) => serde_json::Value::Bool(*b),
LoroValue::Double(d) => {
serde_json::Value::Number(serde_json::Number::from_f64(*d).unwrap())
}
LoroValue::I32(i) => serde_json::Value::Number(serde_json::Number::from(*i)),
LoroValue::String(s) => serde_json::Value::String(s.to_string()),
LoroValue::List(l) => {
serde_json::Value::Array(l.iter().map(|v| v.to_json_value()).collect())
}
LoroValue::Map(m) => serde_json::Value::Object(
m.iter()
.map(|(k, v)| (k.to_string(), v.to_json_value()))
.collect(),
),
LoroValue::Unresolved(id) => {
serde_json::Value::String(serde_json::to_string(id).unwrap())
}
}
}
#[cfg(feature = "json")]
pub fn from_json(s: &str) -> Self {
serde_json::from_str(s).unwrap()