diff --git a/Cargo.lock b/Cargo.lock index eb29bf2a..96d33bc5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,6 +38,12 @@ dependencies = [ "derive_arbitrary", ] +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + [[package]] name = "arref" version = "0.1.0" @@ -121,6 +127,12 @@ version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" +[[package]] +name = "bytecount" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" + [[package]] name = "byteorder" version = "1.4.3" @@ -371,6 +383,7 @@ dependencies = [ "smartstring", "static_assertions", "string_cache", + "tabled", "thiserror", ] @@ -526,6 +539,18 @@ dependencies = [ "syn 1.0.100", ] +[[package]] +name = "papergrid" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae9bed2481d5ab6e31056945f4704ca7348a3858148c30725b8946b7a7818498" +dependencies = [ + "bytecount", + "fnv", + "strip-ansi-escapes", + "unicode-width", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -913,6 +938,15 @@ dependencies = [ "serde", ] +[[package]] +name = "strip-ansi-escapes" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "011cbb39cf7c1f62871aea3cc46e5817b0937b49e9447370c93cacbe93a766d8" +dependencies = [ + "vte", +] + [[package]] name = "syn" version = "0.15.44" @@ -935,6 +969,30 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tabled" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8a1ea336f84dc7dfae1025b73904551b3c6a42347f4243387e990f94325895" +dependencies = [ + "papergrid", + "tabled_derive", + "unicode-width", +] + +[[package]] +name = "tabled_derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beca1b4eaceb4f2755df858b88d9b9315b7ccfd1ffd0d7a48a52602301f01a57" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2 1.0.43", + "quote 1.0.21", + "syn 1.0.100", +] + [[package]] name = "tempfile" version = "3.3.0" @@ -990,6 +1048,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + [[package]] name = "unicode-xid" version = "0.1.0" @@ -1002,12 +1066,39 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "utf8parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372" + [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "vte" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983" +dependencies = [ + "arrayvec", + "utf8parse", + "vte_generate_state_changes", +] + +[[package]] +name = "vte_generate_state_changes" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" +dependencies = [ + "proc-macro2 1.0.43", + "quote 1.0.21", +] + [[package]] name = "wait-timeout" version = "0.2.0" diff --git a/crates/loro-core/Cargo.toml b/crates/loro-core/Cargo.toml index 512e8ff2..fe0a2294 100644 --- a/crates/loro-core/Cargo.toml +++ b/crates/loro-core/Cargo.toml @@ -27,6 +27,7 @@ proptest = "1.0.0" proptest-derive = "0.3.0" rand = "0.8.5" static_assertions = "1.1.0" +tabled = "0.9.0" # See https://matklad.github.io/2021/02/27/delete-cargo-integration-tests.html [lib] diff --git a/crates/loro-core/src/container/text/tracker/y_span.rs b/crates/loro-core/src/container/text/tracker/y_span.rs index 37e92bf7..54f5fb54 100644 --- a/crates/loro-core/src/container/text/tracker/y_span.rs +++ b/crates/loro-core/src/container/text/tracker/y_span.rs @@ -1,3 +1,5 @@ +use std::fmt::Display; + use crate::{id::Counter, span::IdSpan, ContentType, InsertContentTrait, ID}; use rle::{rle_tree::tree_trait::CumulateTreeTrait, HasLength, Mergable, Sliceable}; @@ -9,6 +11,20 @@ pub struct Status { pub undo_times: usize, } +impl Display for Status { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.is_activated() { + write!(f, "Active",) + } else { + write!( + f, + "unapplied: {}, delete_times: {}, undo_times: {}", + self.unapplied, self.delete_times, self.undo_times + ) + } + } +} + impl Status { #[inline] pub fn new() -> Self { @@ -155,6 +171,94 @@ impl HasLength for YSpan { #[cfg(test)] mod test { + use std::borrow::Cow; + + use tabled::{Style, Table, Tabled}; + impl Tabled for YSpan { + const LENGTH: usize = 7; + + fn fields(&self) -> Vec> { + vec![ + self.id.to_string().into(), + self.len.to_string().into(), + self.status.unapplied.to_string().into(), + self.status.delete_times.to_string().into(), + self.status.undo_times.to_string().into(), + self.origin_left + .map(|id| id.to_string()) + .unwrap_or_default() + .into(), + self.origin_right + .map(|id| id.to_string()) + .unwrap_or_default() + .into(), + ] + } + + fn headers() -> Vec> { + vec![ + "id".into(), + "len".into(), + "future".into(), + "del".into(), + "undo".into(), + "origin\nleft".into(), + "origin\nright".into(), + ] + } + } + + #[test] + fn test_table() { + let y_spans = vec![ + YSpan { + id: ID::new(1, 0), + len: 1, + status: Status::new(), + origin_left: None, + origin_right: None, + }, + YSpan { + id: ID::new(1, 1), + len: 1, + status: Status::new(), + origin_left: Some(ID { + client_id: 0, + counter: 2, + }), + origin_right: None, + }, + YSpan { + id: ID::new(1, 2), + len: 1, + status: Status { + unapplied: true, + delete_times: 5, + undo_times: 3, + }, + origin_left: None, + origin_right: None, + }, + YSpan { + id: ID::new(1, 3), + len: 1, + status: Status::new(), + origin_left: None, + origin_right: None, + }, + YSpan { + id: ID::new(1, 4), + len: 1, + status: Status::new(), + origin_left: None, + origin_right: None, + }, + ]; + let mut t = Table::new(y_spans); + t.with(Style::rounded()); + println!("{}", &t) + } + use crate::{ container::{ContainerID, ContainerType}, id::ROOT_ID, @@ -163,7 +267,7 @@ mod test { }; use rle::{HasLength, RleVec}; - use super::YSpan; + use super::{Status, YSpan}; #[test] fn test_merge() { diff --git a/crates/loro-core/src/id.rs b/crates/loro-core/src/id.rs index c6253ac7..aaf4d1c1 100644 --- a/crates/loro-core/src/id.rs +++ b/crates/loro-core/src/id.rs @@ -1,3 +1,5 @@ +use std::fmt::Display; + use serde::Serialize; pub type ClientID = u64; @@ -10,6 +12,12 @@ pub struct ID { pub counter: Counter, } +impl Display for ID { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}:{}", self.client_id, self.counter) + } +} + impl PartialOrd for ID { fn partial_cmp(&self, other: &Self) -> Option { match self.client_id.partial_cmp(&other.client_id) {