document.rs 5.9 KB

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