controller.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  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. self.group_ctx.clone_groups()
  164. }
  165. fn get_group(&self, group_id: &str) -> Option<(usize, Group)> {
  166. let group = self.group_ctx.get_group(group_id)?;
  167. Some((group.0, group.1.clone()))
  168. }
  169. #[tracing::instrument(level = "trace", skip_all, fields(row_count=%row_revs.len(), group_result))]
  170. fn fill_groups(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()> {
  171. for row_rev in row_revs {
  172. let cell_rev = match row_rev.cells.get(&self.field_id) {
  173. None => self.default_cell_rev(),
  174. Some(cell_rev) => Some(cell_rev.clone()),
  175. };
  176. if let Some(cell_rev) = cell_rev {
  177. let mut grouped_rows: Vec<GroupedRow> = vec![];
  178. let cell_bytes = decode_any_cell_data(cell_rev.data, field_rev);
  179. let cell_data = cell_bytes.parser::<P>()?;
  180. for group in self.group_ctx.concrete_groups() {
  181. if self.can_group(&group.filter_content, &cell_data) {
  182. grouped_rows.push(GroupedRow {
  183. row: row_rev.into(),
  184. group_id: group.id.clone(),
  185. });
  186. }
  187. }
  188. if grouped_rows.is_empty() {
  189. self.group_ctx.get_mut_default_group().add_row(row_rev.into());
  190. } else {
  191. for group_row in grouped_rows {
  192. if let Some(group) = self.group_ctx.get_mut_group(&group_row.group_id) {
  193. group.add_row(group_row.row);
  194. }
  195. }
  196. }
  197. } else {
  198. self.group_ctx.get_mut_default_group().add_row(row_rev.into());
  199. }
  200. }
  201. tracing::Span::current().record("group_result", &format!("{},", self.group_ctx,).as_str());
  202. Ok(())
  203. }
  204. fn move_group(&mut self, from_group_id: &str, to_group_id: &str) -> FlowyResult<()> {
  205. self.group_ctx.move_group(from_group_id, to_group_id)
  206. }
  207. fn did_update_row(
  208. &mut self,
  209. row_rev: &RowRevision,
  210. field_rev: &FieldRevision,
  211. ) -> FlowyResult<Vec<GroupChangesetPB>> {
  212. if let Some(cell_rev) = row_rev.cells.get(&self.field_id) {
  213. let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev);
  214. let cell_data = cell_bytes.parser::<P>()?;
  215. let mut changesets = self.add_row_if_match(row_rev, &cell_data);
  216. let default_group_changeset = self.update_default_group(row_rev, &changesets);
  217. tracing::info!("default_group_changeset: {}", default_group_changeset);
  218. if !default_group_changeset.is_empty() {
  219. changesets.push(default_group_changeset);
  220. }
  221. Ok(changesets)
  222. } else {
  223. Ok(vec![])
  224. }
  225. }
  226. fn did_delete_row(
  227. &mut self,
  228. row_rev: &RowRevision,
  229. field_rev: &FieldRevision,
  230. ) -> FlowyResult<Vec<GroupChangesetPB>> {
  231. if let Some(cell_rev) = row_rev.cells.get(&self.field_id) {
  232. let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev);
  233. let cell_data = cell_bytes.parser::<P>()?;
  234. Ok(self.remove_row_if_match(row_rev, &cell_data))
  235. } else {
  236. Ok(vec![])
  237. }
  238. }
  239. fn move_group_row(&mut self, context: MoveGroupRowContext) -> FlowyResult<Vec<GroupChangesetPB>> {
  240. if let Some(cell_rev) = context.row_rev.cells.get(&self.field_id) {
  241. let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), context.field_rev);
  242. let cell_data = cell_bytes.parser::<P>()?;
  243. Ok(self.move_row(&cell_data, context))
  244. } else {
  245. Ok(vec![])
  246. }
  247. }
  248. fn did_update_field(&mut self, field_rev: &FieldRevision) -> FlowyResult<Option<GroupViewChangesetPB>> {
  249. let type_option = field_rev.get_type_option::<T>(field_rev.ty);
  250. let groups = G::generate_groups(&field_rev.id, &self.group_ctx, &type_option);
  251. let changeset = self.group_ctx.init_groups(groups, false)?;
  252. Ok(changeset)
  253. }
  254. }
  255. struct GroupedRow {
  256. row: RowPB,
  257. group_id: String,
  258. }