document.rs 6.8 KB

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