document.rs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. use crate::{
  2. errors::DocError,
  3. services::doc::{view::View, History, UndoResult, RECORD_THRESHOLD},
  4. };
  5. use flowy_ot::core::*;
  6. use tokio::sync::mpsc;
  7. pub trait CustomDocument {
  8. fn init_delta() -> Delta;
  9. }
  10. pub struct PlainDoc();
  11. impl CustomDocument for PlainDoc {
  12. fn init_delta() -> Delta { Delta::new() }
  13. }
  14. #[allow(dead_code)]
  15. #[inline]
  16. pub fn doc_initial_delta() -> Delta { DeltaBuilder::new().insert("\n").build() }
  17. #[allow(dead_code)]
  18. #[inline]
  19. pub fn doc_initial_string() -> String { doc_initial_delta().to_json() }
  20. #[allow(dead_code)]
  21. #[inline]
  22. pub fn doc_initial_bytes() -> Vec<u8> { doc_initial_string().into_bytes() }
  23. pub struct FlowyDoc();
  24. impl CustomDocument for FlowyDoc {
  25. fn init_delta() -> Delta { doc_initial_delta() }
  26. }
  27. pub struct Document {
  28. delta: Delta,
  29. history: History,
  30. view: View,
  31. last_edit_time: usize,
  32. notify: Option<mpsc::UnboundedSender<()>>,
  33. }
  34. impl Document {
  35. pub fn new<C: CustomDocument>() -> Self { Self::from_delta(C::init_delta()) }
  36. pub fn from_delta(delta: Delta) -> Self {
  37. Document {
  38. delta,
  39. history: History::new(),
  40. view: View::new(),
  41. last_edit_time: 0,
  42. notify: None,
  43. }
  44. }
  45. pub fn from_json(json: &str) -> Result<Self, DocError> {
  46. let delta = Delta::from_json(json)?;
  47. Ok(Self::from_delta(delta))
  48. }
  49. pub fn to_json(&self) -> String { self.delta.to_json() }
  50. pub fn to_bytes(&self) -> Vec<u8> { self.delta.clone().to_bytes().to_vec() }
  51. pub fn to_plain_string(&self) -> String { self.delta.apply("").unwrap() }
  52. pub fn delta(&self) -> &Delta { &self.delta }
  53. pub fn set_notify(&mut self, notify: mpsc::UnboundedSender<()>) { self.notify = Some(notify); }
  54. pub fn set_delta(&mut self, data: Delta) {
  55. self.delta = data;
  56. match &self.notify {
  57. None => {},
  58. Some(notify) => {
  59. let _ = notify.send(());
  60. },
  61. }
  62. }
  63. pub fn compose_delta(&mut self, mut delta: Delta) -> Result<(), DocError> {
  64. trim(&mut delta);
  65. tracing::trace!("{} compose {}", &self.delta.to_json(), delta.to_json());
  66. let mut composed_delta = self.delta.compose(&delta)?;
  67. let mut undo_delta = delta.invert(&self.delta);
  68. let now = chrono::Utc::now().timestamp_millis() as usize;
  69. if now - self.last_edit_time < RECORD_THRESHOLD {
  70. if let Some(last_delta) = self.history.undo() {
  71. tracing::trace!("compose previous change");
  72. tracing::trace!("current = {}", undo_delta);
  73. tracing::trace!("previous = {}", last_delta);
  74. undo_delta = undo_delta.compose(&last_delta)?;
  75. }
  76. } else {
  77. self.last_edit_time = now;
  78. }
  79. tracing::trace!("👉 receive change undo: {}", undo_delta);
  80. if !undo_delta.is_empty() {
  81. self.history.record(undo_delta);
  82. }
  83. tracing::trace!("compose result: {}", composed_delta.to_json());
  84. trim(&mut composed_delta);
  85. self.set_delta(composed_delta);
  86. Ok(())
  87. }
  88. pub fn insert<T: ToString>(&mut self, index: usize, data: T) -> Result<Delta, DocError> {
  89. let interval = Interval::new(index, index);
  90. let _ = validate_interval(&self.delta, &interval)?;
  91. let text = data.to_string();
  92. let delta = self.view.insert(&self.delta, &text, interval)?;
  93. tracing::trace!("👉 receive change: {}", delta);
  94. self.compose_delta(delta.clone())?;
  95. Ok(delta)
  96. }
  97. pub fn delete(&mut self, interval: Interval) -> Result<Delta, DocError> {
  98. let _ = validate_interval(&self.delta, &interval)?;
  99. debug_assert_eq!(interval.is_empty(), false);
  100. let delete = self.view.delete(&self.delta, interval)?;
  101. if !delete.is_empty() {
  102. tracing::trace!("👉 receive change: {}", delete);
  103. let _ = self.compose_delta(delete.clone())?;
  104. }
  105. Ok(delete)
  106. }
  107. pub fn format(&mut self, interval: Interval, attribute: Attribute) -> Result<Delta, DocError> {
  108. let _ = validate_interval(&self.delta, &interval)?;
  109. tracing::trace!("format with {} at {}", attribute, interval);
  110. let format_delta = self.view.format(&self.delta, attribute.clone(), interval).unwrap();
  111. tracing::trace!("👉 receive change: {}", format_delta);
  112. self.compose_delta(format_delta.clone())?;
  113. Ok(format_delta)
  114. }
  115. pub fn replace<T: ToString>(&mut self, interval: Interval, data: T) -> Result<Delta, DocError> {
  116. let _ = validate_interval(&self.delta, &interval)?;
  117. let mut delta = Delta::default();
  118. let text = data.to_string();
  119. if !text.is_empty() {
  120. delta = self.view.insert(&self.delta, &text, interval)?;
  121. tracing::trace!("👉 receive change: {}", delta);
  122. self.compose_delta(delta.clone())?;
  123. }
  124. if !interval.is_empty() {
  125. let delete = self.delete(interval)?;
  126. delta = delta.compose(&delete)?;
  127. }
  128. Ok(delta)
  129. }
  130. pub fn can_undo(&self) -> bool { self.history.can_undo() }
  131. pub fn can_redo(&self) -> bool { self.history.can_redo() }
  132. pub fn undo(&mut self) -> Result<UndoResult, DocError> {
  133. match self.history.undo() {
  134. None => Err(DocError::undo().context("Undo stack is empty")),
  135. Some(undo_delta) => {
  136. let (new_delta, inverted_delta) = self.invert(&undo_delta)?;
  137. let result = UndoResult::success(new_delta.target_len as usize);
  138. self.set_delta(new_delta);
  139. self.history.add_redo(inverted_delta);
  140. Ok(result)
  141. },
  142. }
  143. }
  144. pub fn redo(&mut self) -> Result<UndoResult, DocError> {
  145. match self.history.redo() {
  146. None => Err(DocError::redo()),
  147. Some(redo_delta) => {
  148. let (new_delta, inverted_delta) = self.invert(&redo_delta)?;
  149. let result = UndoResult::success(new_delta.target_len as usize);
  150. self.set_delta(new_delta);
  151. self.history.add_undo(inverted_delta);
  152. Ok(result)
  153. },
  154. }
  155. }
  156. }
  157. impl Document {
  158. fn invert(&self, delta: &Delta) -> Result<(Delta, Delta), DocError> {
  159. // c = a.compose(b)
  160. // d = b.invert(a)
  161. // a = c.compose(d)
  162. tracing::trace!("Invert {}", delta);
  163. let new_delta = self.delta.compose(delta)?;
  164. let inverted_delta = delta.invert(&self.delta);
  165. Ok((new_delta, inverted_delta))
  166. }
  167. }
  168. fn validate_interval(delta: &Delta, interval: &Interval) -> Result<(), DocError> {
  169. if delta.target_len < interval.end {
  170. log::error!("{:?} out of bounds. should 0..{}", interval, delta.target_len);
  171. return Err(DocError::out_of_bound());
  172. }
  173. Ok(())
  174. }
  175. /// Removes trailing retain operation with empty attributes, if present.
  176. pub fn trim(delta: &mut Delta) {
  177. if let Some(last) = delta.ops.last() {
  178. if last.is_retain() && last.is_plain() {
  179. delta.ops.pop();
  180. }
  181. }
  182. }