view_revision_pad.rs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. use crate::entities::revision::{md5, Revision};
  2. use crate::errors::{internal_error, CollaborateError, CollaborateResult};
  3. use crate::util::{cal_diff, make_text_delta_from_revisions};
  4. use flowy_grid_data_model::revision::{
  5. FieldRevision, FieldTypeRevision, FilterConfigurationRevision, FilterConfigurationsByFieldId, GridViewRevision,
  6. GroupConfigurationRevision, GroupConfigurationsByFieldId,
  7. };
  8. use lib_ot::core::{OperationTransform, PhantomAttributes, TextDelta, TextDeltaBuilder};
  9. use std::sync::Arc;
  10. #[derive(Debug, Clone)]
  11. pub struct GridViewRevisionPad {
  12. view: Arc<GridViewRevision>,
  13. delta: TextDelta,
  14. }
  15. impl std::ops::Deref for GridViewRevisionPad {
  16. type Target = GridViewRevision;
  17. fn deref(&self) -> &Self::Target {
  18. &self.view
  19. }
  20. }
  21. impl GridViewRevisionPad {
  22. pub fn new(grid_id: String, view_id: String) -> Self {
  23. let view = Arc::new(GridViewRevision::new(grid_id, view_id));
  24. let json = serde_json::to_string(&view).unwrap();
  25. let delta = TextDeltaBuilder::new().insert(&json).build();
  26. Self { view, delta }
  27. }
  28. pub fn from_delta(delta: TextDelta) -> CollaborateResult<Self> {
  29. let s = delta.content()?;
  30. let view: GridViewRevision = serde_json::from_str(&s).map_err(|e| {
  31. let msg = format!("Deserialize delta to GridViewRevision failed: {}", e);
  32. tracing::error!("{}", s);
  33. CollaborateError::internal().context(msg)
  34. })?;
  35. Ok(Self {
  36. view: Arc::new(view),
  37. delta,
  38. })
  39. }
  40. pub fn from_revisions(_grid_id: &str, revisions: Vec<Revision>) -> CollaborateResult<Self> {
  41. let delta: TextDelta = make_text_delta_from_revisions(revisions)?;
  42. Self::from_delta(delta)
  43. }
  44. pub fn get_all_groups(&self, field_revs: &[Arc<FieldRevision>]) -> Option<GroupConfigurationsByFieldId> {
  45. self.groups.get_all_objects(field_revs)
  46. }
  47. #[tracing::instrument(level = "trace", skip_all, err)]
  48. pub fn insert_group(
  49. &mut self,
  50. field_id: &str,
  51. field_type: &FieldTypeRevision,
  52. group_rev: GroupConfigurationRevision,
  53. ) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
  54. self.modify(|view| {
  55. view.groups.insert_object(field_id, field_type, group_rev);
  56. Ok(Some(()))
  57. })
  58. }
  59. #[tracing::instrument(level = "trace", skip_all)]
  60. pub fn contains_group(&self, field_id: &str, field_type: &FieldTypeRevision) -> bool {
  61. self.view.groups.get_objects(field_id, field_type).is_some()
  62. }
  63. #[tracing::instrument(level = "trace", skip_all, err)]
  64. pub fn with_mut_group<F: FnOnce(&mut GroupConfigurationRevision)>(
  65. &mut self,
  66. field_id: &str,
  67. field_type: &FieldTypeRevision,
  68. configuration_id: &str,
  69. mut_configuration_fn: F,
  70. ) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
  71. self.modify(|view| match view.groups.get_mut_objects(field_id, field_type) {
  72. None => Ok(None),
  73. Some(configurations_revs) => {
  74. for configuration_rev in configurations_revs {
  75. if configuration_rev.id == configuration_id {
  76. mut_configuration_fn(Arc::make_mut(configuration_rev));
  77. return Ok(Some(()));
  78. }
  79. }
  80. Ok(None)
  81. }
  82. })
  83. }
  84. pub fn delete_group(
  85. &mut self,
  86. field_id: &str,
  87. field_type: &FieldTypeRevision,
  88. group_id: &str,
  89. ) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
  90. self.modify(|view| {
  91. if let Some(groups) = view.groups.get_mut_objects(field_id, field_type) {
  92. groups.retain(|group| group.id != group_id);
  93. Ok(Some(()))
  94. } else {
  95. Ok(None)
  96. }
  97. })
  98. }
  99. pub fn get_all_filters(&self, field_revs: &[Arc<FieldRevision>]) -> Option<FilterConfigurationsByFieldId> {
  100. self.filters.get_all_objects(field_revs)
  101. }
  102. pub fn get_filters(
  103. &self,
  104. field_id: &str,
  105. field_type_rev: &FieldTypeRevision,
  106. ) -> Option<Vec<Arc<FilterConfigurationRevision>>> {
  107. self.filters.get_objects(field_id, field_type_rev)
  108. }
  109. pub fn insert_filter(
  110. &mut self,
  111. field_id: &str,
  112. field_type: &FieldTypeRevision,
  113. filter_rev: FilterConfigurationRevision,
  114. ) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
  115. self.modify(|view| {
  116. view.filters.insert_object(field_id, field_type, filter_rev);
  117. Ok(Some(()))
  118. })
  119. }
  120. pub fn delete_filter(
  121. &mut self,
  122. field_id: &str,
  123. field_type: &FieldTypeRevision,
  124. filter_id: &str,
  125. ) -> CollaborateResult<Option<GridViewRevisionChangeset>> {
  126. self.modify(|view| {
  127. if let Some(filters) = view.filters.get_mut_objects(field_id, field_type) {
  128. filters.retain(|filter| filter.id != filter_id);
  129. Ok(Some(()))
  130. } else {
  131. Ok(None)
  132. }
  133. })
  134. }
  135. pub fn json_str(&self) -> CollaborateResult<String> {
  136. make_grid_view_rev_json_str(&self.view)
  137. }
  138. fn modify<F>(&mut self, f: F) -> CollaborateResult<Option<GridViewRevisionChangeset>>
  139. where
  140. F: FnOnce(&mut GridViewRevision) -> CollaborateResult<Option<()>>,
  141. {
  142. let cloned_view = self.view.clone();
  143. match f(Arc::make_mut(&mut self.view))? {
  144. None => Ok(None),
  145. Some(_) => {
  146. let old = make_grid_view_rev_json_str(&cloned_view)?;
  147. let new = self.json_str()?;
  148. match cal_diff::<PhantomAttributes>(old, new) {
  149. None => Ok(None),
  150. Some(delta) => {
  151. self.delta = self.delta.compose(&delta)?;
  152. tracing::info!("GridView: {:?}", delta);
  153. let md5 = md5(&self.delta.json_bytes());
  154. Ok(Some(GridViewRevisionChangeset { delta, md5 }))
  155. }
  156. }
  157. }
  158. }
  159. }
  160. }
  161. #[derive(Debug)]
  162. pub struct GridViewRevisionChangeset {
  163. pub delta: TextDelta,
  164. pub md5: String,
  165. }
  166. pub fn make_grid_view_rev_json_str(grid_revision: &GridViewRevision) -> CollaborateResult<String> {
  167. let json = serde_json::to_string(grid_revision)
  168. .map_err(|err| internal_error(format!("Serialize grid view to json str failed. {:?}", err)))?;
  169. Ok(json)
  170. }
  171. pub fn make_grid_view_delta(grid_view: &GridViewRevision) -> TextDelta {
  172. let json = serde_json::to_string(grid_view).unwrap();
  173. TextDeltaBuilder::new().insert(&json).build()
  174. }