Skip to content

Commit

Permalink
fix: to_delta return TextDelta
Browse files Browse the repository at this point in the history
  • Loading branch information
Leeeon233 committed Jan 8, 2025
1 parent 32d5c9b commit 763ab04
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 52 deletions.
52 changes: 48 additions & 4 deletions crates/loro-ffi/src/container/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,50 @@ impl LoroText {
self.text.unmark(from as usize..to as usize, key)
}

/// Get the text in [Delta](https://quilljs.com/docs/delta/) format.
///
/// # Example
/// ```
/// use loro::{LoroDoc, ToJson, ExpandType, TextDelta};
/// use serde_json::json;
/// use std::collections::HashMap;
///
/// let doc = LoroDoc::new();
/// let text = doc.get_text("text");
/// text.insert(0, "Hello world!").unwrap();
/// text.mark(0..5, "bold", true).unwrap();
/// assert_eq!(
/// text.to_delta(),
/// vec![
/// TextDelta::Insert {
/// insert: "Hello".to_string(),
/// attributes: Some(HashMap::from_iter([("bold".to_string(), true.into())])),
/// },
/// TextDelta::Insert {
/// insert: " world!".to_string(),
/// attributes: None,
/// },
/// ]
/// );
/// text.unmark(3..5, "bold").unwrap();
/// assert_eq!(
/// text.to_delta(),
/// vec![
/// TextDelta::Insert {
/// insert: "Hel".to_string(),
/// attributes: Some(HashMap::from_iter([("bold".to_string(), true.into())])),
/// },
/// TextDelta::Insert {
/// insert: "lo world!".to_string(),
/// attributes: None,
/// },
/// ]
/// );
/// ```
pub fn to_delta(&self) -> Vec<TextDelta> {
self.text.to_delta().into_iter().map(|d| d.into()).collect()
}

/// Get the text in [Delta](https://quilljs.com/docs/delta/) format.
///
/// # Example
Expand All @@ -170,23 +214,23 @@ impl LoroText {
/// text.insert(0, "Hello world!").unwrap();
/// text.mark(0..5, "bold", true).unwrap();
/// assert_eq!(
/// text.to_delta().to_json_value(),
/// text.get_richtext_value().to_json_value(),
/// json!([
/// { "insert": "Hello", "attributes": {"bold": true} },
/// { "insert": " world!" },
/// ])
/// );
/// text.unmark(3..5, "bold").unwrap();
/// assert_eq!(
/// text.to_delta().to_json_value(),
/// text.get_richtext_value().to_json_value(),
/// json!([
/// { "insert": "Hel", "attributes": {"bold": true} },
/// { "insert": "lo world!" },
/// ])
/// );
/// ```
pub fn to_delta(&self) -> LoroValue {
self.text.to_delta().into()
pub fn get_richtext_value(&self) -> LoroValue {
self.text.get_richtext_value().into()
}

/// Get the cursor at the given position.
Expand Down
26 changes: 26 additions & 0 deletions crates/loro-ffi/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,32 @@ impl From<TextDelta> for loro_internal::handler::TextDelta {
}
}

impl From<loro::TextDelta> for TextDelta {
fn from(value: loro::TextDelta) -> Self {
match value {
loro::TextDelta::Retain { retain, attributes } => TextDelta::Retain {
retain: retain as u32,
attributes: attributes.as_ref().map(|a| {
a.iter()
.map(|(k, v)| (k.to_string(), v.clone().into()))
.collect()
}),
},
loro::TextDelta::Insert { insert, attributes } => TextDelta::Insert {
insert,
attributes: attributes.as_ref().map(|a| {
a.iter()
.map(|(k, v)| (k.to_string(), v.clone().into()))
.collect()
}),
},
loro::TextDelta::Delete { delete } => TextDelta::Delete {
delete: delete as u32,
},
}
}
}

pub enum ListDiffItem {
/// Insert a new element into the list.
Insert {
Expand Down
6 changes: 3 additions & 3 deletions crates/loro/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,15 @@ let text = doc.get_text("text");
text.insert(0, "Hello world!").unwrap();
text.mark(0..5, "bold", true).unwrap();
assert_eq!(
text.to_delta().to_json_value(),
text.get_richtext_value().to_json_value(),
json!([
{ "insert": "Hello", "attributes": {"bold": true} },
{ "insert": " world!" },
])
);
text.unmark(3..5, "bold").unwrap();
assert_eq!(
text.to_delta().to_json_value(),
text.get_richtext_value().to_json_value(),
json!([
{ "insert": "Hel", "attributes": {"bold": true} },
{ "insert": "lo world!" },
Expand All @@ -86,7 +86,7 @@ text_b
.unwrap();
doc.import(&doc_b.export_from(&doc.oplog_vv())).unwrap();
assert_eq!(
text.to_delta().to_json_value(),
text.get_richtext_value().to_json_value(),
json!([
{ "insert": "Hello", "attributes": {"bold": true} },
{ "insert": " world!" },
Expand Down
64 changes: 60 additions & 4 deletions crates/loro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use loro_internal::{
};
use std::cmp::Ordering;
use std::ops::ControlFlow;
use std::ops::Deref;
use std::ops::Range;
use std::sync::Arc;
use tracing::info;
Expand Down Expand Up @@ -1632,30 +1633,85 @@ impl LoroText {
///
/// # Example
/// ```
/// # use loro::{LoroDoc, ToJson, ExpandType};
/// use loro::{LoroDoc, ToJson, ExpandType, TextDelta};
/// use serde_json::json;
/// use fxhash::FxHashMap;
///
/// let doc = LoroDoc::new();
/// let text = doc.get_text("text");
/// text.insert(0, "Hello world!").unwrap();
/// text.mark(0..5, "bold", true).unwrap();
/// assert_eq!(
/// text.to_delta(),
/// vec![
/// TextDelta::Insert {
/// insert: "Hello".to_string(),
/// attributes: Some(FxHashMap::from_iter([("bold".to_string(), true.into())])),
/// },
/// TextDelta::Insert {
/// insert: " world!".to_string(),
/// attributes: None,
/// },
/// ]
/// );
/// text.unmark(3..5, "bold").unwrap();
/// assert_eq!(
/// text.to_delta(),
/// vec![
/// TextDelta::Insert {
/// insert: "Hel".to_string(),
/// attributes: Some(FxHashMap::from_iter([("bold".to_string(), true.into())])),
/// },
/// TextDelta::Insert {
/// insert: "lo world!".to_string(),
/// attributes: None,
/// },
/// ]
/// );
/// ```
pub fn to_delta(&self) -> Vec<TextDelta> {
let delta = self.handler.get_richtext_value().into_list().unwrap();
delta
.iter()
.map(|x| {
let map = x.as_map().unwrap();
let insert = map.get("insert").unwrap().as_string().unwrap().to_string();
let attributes = map
.get("attributes")
.map(|v| v.as_map().unwrap().deref().clone());
TextDelta::Insert { insert, attributes }
})
.collect()
}

/// Get the rich text value in [Delta](https://quilljs.com/docs/delta/) format.
///
/// # Example
/// ```
/// # use loro::{LoroDoc, ToJson, ExpandType, TextDelta};
/// # use serde_json::json;
///
/// let doc = LoroDoc::new();
/// let text = doc.get_text("text");
/// text.insert(0, "Hello world!").unwrap();
/// text.mark(0..5, "bold", true).unwrap();
/// assert_eq!(
/// text.to_delta().to_json_value(),
/// text.get_richtext_value().to_json_value(),
/// json!([
/// { "insert": "Hello", "attributes": {"bold": true} },
/// { "insert": " world!" },
/// ])
/// );
/// text.unmark(3..5, "bold").unwrap();
/// assert_eq!(
/// text.to_delta().to_json_value(),
/// text.get_richtext_value().to_json_value(),
/// json!([
/// { "insert": "Hel", "attributes": {"bold": true} },
/// { "insert": "lo world!" },
/// ])
/// );
/// ```
pub fn to_delta(&self) -> LoroValue {
pub fn get_richtext_value(&self) -> LoroValue {
self.handler.get_richtext_value()
}

Expand Down
Loading

0 comments on commit 763ab04

Please sign in to comment.