document.rs 5.7 KB

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