controller.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. use crate::entities::{GroupChangesetPB, GroupViewChangesetPB, InsertedRowPB, RowPB};
  2. use crate::services::cell::{decode_any_cell_data, CellBytesParser};
  3. use crate::services::group::action::GroupAction;
  4. use crate::services::group::configuration::GroupContext;
  5. use crate::services::group::entities::Group;
  6. use flowy_error::FlowyResult;
  7. use flowy_grid_data_model::revision::{
  8. FieldRevision, GroupConfigurationContentSerde, GroupRevision, RowChangeset, RowRevision, TypeOptionDataDeserializer,
  9. };
  10. use std::marker::PhantomData;
  11. use std::sync::Arc;
  12. // Each kind of group must implement this trait to provide custom group
  13. // operations. For example, insert cell data to the row_rev when creating
  14. // a new row.
  15. pub trait GroupController: GroupControllerSharedOperation + Send + Sync {
  16. fn will_create_row(&mut self, row_rev: &mut RowRevision, field_rev: &FieldRevision, group_id: &str);
  17. }
  18. pub trait GroupGenerator {
  19. type Context;
  20. type TypeOptionType;
  21. fn generate_groups(
  22. field_id: &str,
  23. group_ctx: &Self::Context,
  24. type_option: &Option<Self::TypeOptionType>,
  25. ) -> Vec<GeneratedGroup>;
  26. }
  27. pub struct GeneratedGroup {
  28. pub group_rev: GroupRevision,
  29. pub filter_content: String,
  30. }
  31. pub struct MoveGroupRowContext<'a> {
  32. pub row_rev: &'a RowRevision,
  33. pub row_changeset: &'a mut RowChangeset,
  34. pub field_rev: &'a FieldRevision,
  35. pub to_group_id: &'a str,
  36. pub to_row_id: Option<String>,
  37. }
  38. // Defines the shared actions each group controller can perform.
  39. pub trait GroupControllerSharedOperation: Send + Sync {
  40. // The field that is used for grouping the rows
  41. fn field_id(&self) -> &str;
  42. fn groups(&self) -> Vec<Group>;
  43. fn get_group(&self, group_id: &str) -> Option<(usize, Group)>;
  44. fn fill_groups(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()>;
  45. fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()>;
  46. fn did_update_row(
  47. &mut self,
  48. row_rev: &RowRevision,
  49. field_rev: &FieldRevision,
  50. ) -> FlowyResult<Vec<GroupChangesetPB>>;
  51. fn did_delete_row(
  52. &mut self,
  53. row_rev: &RowRevision,
  54. field_rev: &FieldRevision,
  55. ) -> FlowyResult<Vec<GroupChangesetPB>>;
  56. fn move_group_row(&mut self, context: MoveGroupRowContext) -> FlowyResult<Vec<GroupChangesetPB>>;
  57. fn did_update_field(&mut self, field_rev: &FieldRevision) -> FlowyResult<Option<GroupViewChangesetPB>>;
  58. }
  59. /// C: represents the group configuration that impl [GroupConfigurationSerde]
  60. /// T: the type option data deserializer that impl [TypeOptionDataDeserializer]
  61. /// G: the group generator, [GroupGenerator]
  62. /// P: the parser that impl [CellBytesParser] for the CellBytes
  63. pub struct GenericGroupController<C, T, G, P> {
  64. pub field_id: String,
  65. pub type_option: Option<T>,
  66. pub group_ctx: GroupContext<C>,
  67. group_action_phantom: PhantomData<G>,
  68. cell_parser_phantom: PhantomData<P>,
  69. }
  70. impl<C, T, G, P> GenericGroupController<C, T, G, P>
  71. where
  72. C: GroupConfigurationContentSerde,
  73. T: TypeOptionDataDeserializer,
  74. G: GroupGenerator<Context = GroupContext<C>, TypeOptionType = T>,
  75. {
  76. pub async fn new(field_rev: &Arc<FieldRevision>, mut configuration: GroupContext<C>) -> FlowyResult<Self> {
  77. let field_type_rev = field_rev.ty;
  78. let type_option = field_rev.get_type_option::<T>(field_type_rev);
  79. let groups = G::generate_groups(&field_rev.id, &configuration, &type_option);
  80. let _ = configuration.init_groups(groups, false)?;
  81. Ok(Self {
  82. field_id: field_rev.id.clone(),
  83. type_option,
  84. group_ctx: configuration,
  85. group_action_phantom: PhantomData,
  86. cell_parser_phantom: PhantomData,
  87. })
  88. }
  89. // https://stackoverflow.com/questions/69413164/how-to-fix-this-clippy-warning-needless-collect
  90. #[allow(clippy::needless_collect)]
  91. fn update_default_group(
  92. &mut self,
  93. row_rev: &RowRevision,
  94. other_group_changesets: &[GroupChangesetPB],
  95. ) -> GroupChangesetPB {
  96. let default_group = self.group_ctx.get_mut_default_group();
  97. // [other_group_inserted_row] contains all the inserted rows except the default group.
  98. let other_group_inserted_row = other_group_changesets
  99. .iter()
  100. .flat_map(|changeset| &changeset.inserted_rows)
  101. .collect::<Vec<&InsertedRowPB>>();
  102. // Calculate the inserted_rows of the default_group
  103. let default_group_inserted_row = other_group_changesets
  104. .iter()
  105. .flat_map(|changeset| &changeset.deleted_rows)
  106. .cloned()
  107. .filter(|row_id| {
  108. // if the [other_group_inserted_row] contains the row_id of the row
  109. // which means the row should not move to the default group.
  110. !other_group_inserted_row
  111. .iter()
  112. .any(|inserted_row| &inserted_row.row.id == row_id)
  113. })
  114. .collect::<Vec<String>>();
  115. let mut changeset = GroupChangesetPB::new(default_group.id.clone());
  116. if !default_group_inserted_row.is_empty() {
  117. changeset.inserted_rows.push(InsertedRowPB::new(row_rev.into()));
  118. default_group.add_row(row_rev.into());
  119. }
  120. // [other_group_delete_rows] contains all the deleted rows except the default group.
  121. let other_group_delete_rows: Vec<String> = other_group_changesets
  122. .iter()
  123. .flat_map(|changeset| &changeset.deleted_rows)
  124. .cloned()
  125. .collect();
  126. let default_group_deleted_rows = other_group_changesets
  127. .iter()
  128. .flat_map(|changeset| &changeset.inserted_rows)
  129. .filter(|inserted_row| {
  130. // if the [other_group_delete_rows] contain the inserted_row, which means this row should move
  131. // out from the default_group.
  132. let inserted_row_id = &inserted_row.row.id;
  133. !other_group_delete_rows.iter().any(|row_id| inserted_row_id == row_id)
  134. })
  135. .collect::<Vec<&InsertedRowPB>>();
  136. let mut deleted_row_ids = vec![];
  137. for row in &default_group.rows {
  138. if default_group_deleted_rows
  139. .iter()
  140. .any(|deleted_row| deleted_row.row.id == row.id)
  141. {
  142. deleted_row_ids.push(row.id.clone());
  143. }
  144. }
  145. default_group.rows.retain(|row| !deleted_row_ids.contains(&row.id));
  146. changeset.deleted_rows.extend(deleted_row_ids);
  147. changeset
  148. }
  149. }
  150. impl<C, T, G, P> GroupControllerSharedOperation for GenericGroupController<C, T, G, P>
  151. where
  152. P: CellBytesParser,
  153. C: GroupConfigurationContentSerde,
  154. T: TypeOptionDataDeserializer,
  155. G: GroupGenerator<Context = GroupContext<C>, TypeOptionType = T>,
  156. Self: GroupAction<CellDataType = P::Object>,
  157. {
  158. fn field_id(&self) -> &str {
  159. &self.field_id
  160. }
  161. fn groups(&self) -> Vec<Group> {
  162. self.group_ctx.clone_groups()
  163. }
  164. fn get_group(&self, group_id: &str) -> Option<(usize, Group)> {
  165. let group = self.group_ctx.get_group(group_id)?;
  166. Some((group.0, group.1.clone()))
  167. }
  168. #[tracing::instrument(level = "trace", skip_all, fields(row_count=%row_revs.len(), group_result))]
  169. fn fill_groups(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
  170. for row_rev in row_revs {
  171. if let Some(cell_rev) = row_rev.cells.get(&self.field_id) {
  172. let mut grouped_rows: Vec<GroupedRow> = vec![];
  173. let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev);
  174. let cell_data = cell_bytes.parser::<P>()?;
  175. for group in self.group_ctx.concrete_groups() {
  176. if self.can_group(&group.filter_content, &cell_data) {
  177. grouped_rows.push(GroupedRow {
  178. row: row_rev.into(),
  179. group_id: group.id.clone(),
  180. });
  181. }
  182. }
  183. if grouped_rows.is_empty() {
  184. self.group_ctx.get_mut_default_group().add_row(row_rev.into());
  185. } else {
  186. for group_row in grouped_rows {
  187. if let Some(group) = self.group_ctx.get_mut_group(&group_row.group_id) {
  188. group.add_row(group_row.row);
  189. }
  190. }
  191. }
  192. } else {
  193. self.group_ctx.get_mut_default_group().add_row(row_rev.into());
  194. }
  195. }
  196. tracing::Span::current().record("group_result", &format!("{},", self.group_ctx,).as_str());
  197. Ok(())
  198. }
  199. fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()> {
  200. self.group_ctx.move_group(from_group_id, to_group_id)
  201. }
  202. fn did_update_row(
  203. &mut self,
  204. row_rev: &RowRevision,
  205. field_rev: &FieldRevision,
  206. ) -> FlowyResult<Vec<GroupChangesetPB>> {
  207. if let Some(cell_rev) = row_rev.cells.get(&self.field_id) {
  208. let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev);
  209. let cell_data = cell_bytes.parser::<P>()?;
  210. let mut changesets = self.add_row_if_match(row_rev, &cell_data);
  211. let default_group_changeset = self.update_default_group(row_rev, &changesets);
  212. tracing::info!("default_group_changeset: {}", default_group_changeset);
  213. if !default_group_changeset.is_empty() {
  214. changesets.push(default_group_changeset);
  215. }
  216. Ok(changesets)
  217. } else {
  218. Ok(vec![])
  219. }
  220. }
  221. fn did_delete_row(
  222. &mut self,
  223. row_rev: &RowRevision,
  224. field_rev: &FieldRevision,
  225. ) -> FlowyResult<Vec<GroupChangesetPB>> {
  226. if let Some(cell_rev) = row_rev.cells.get(&self.field_id) {
  227. let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev);
  228. let cell_data = cell_bytes.parser::<P>()?;
  229. Ok(self.remove_row_if_match(row_rev, &cell_data))
  230. } else {
  231. Ok(vec![])
  232. }
  233. }
  234. fn move_group_row(&mut self, context: MoveGroupRowContext) -> FlowyResult<Vec<GroupChangesetPB>> {
  235. if let Some(cell_rev) = context.row_rev.cells.get(&self.field_id) {
  236. let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), context.field_rev);
  237. let cell_data = cell_bytes.parser::<P>()?;
  238. Ok(self.move_row(&cell_data, context))
  239. } else {
  240. Ok(vec![])
  241. }
  242. }
  243. fn did_update_field(&mut self, field_rev: &FieldRevision) -> FlowyResult<Option<GroupViewChangesetPB>> {
  244. let type_option = field_rev.get_type_option::<T>(field_rev.ty);
  245. let groups = G::generate_groups(&field_rev.id, &self.group_ctx, &type_option);
  246. let changeset = self.group_ctx.init_groups(groups, false)?;
  247. Ok(changeset)
  248. }
  249. }
  250. struct GroupedRow {
  251. row: RowPB,
  252. group_id: String,
  253. }