controller.rs 11 KB

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