diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 0861f2aaa1..22dff6e191 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -24,7 +24,7 @@ pub(crate) async fn get_rows_handler( ) -> DataResult { let payload: QueryRowPayload = data.into_inner(); let editor = manager.get_grid_editor(&payload.grid_id)?; - let repeated_row: RepeatedRow = editor.get_rows(Some(payload.row_orders)).await?.into(); + let repeated_row: RepeatedRow = editor.get_rows(payload.row_orders).await?.into(); data_result(repeated_row) } @@ -50,10 +50,10 @@ pub(crate) async fn create_row_handler( Ok(()) } -#[tracing::instrument(level = "debug", skip(data, manager), err)] +#[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn update_cell_handler( data: Data, - manager: AppData>, + _manager: AppData>, ) -> Result<(), FlowyError> { let _cell: Cell = data.into_inner(); // let editor = manager.get_grid_editor(id.as_ref())?; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs index 86dab02b67..8b75389ce4 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/field_builder.rs @@ -2,7 +2,7 @@ use crate::services::field::{ CheckboxDescription, DateDescription, DateFormat, MoneySymbol, MultiSelectDescription, NumberDescription, RichTextDescription, SelectOption, SingleSelectDescription, TimeFormat, }; -use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; +use flowy_grid_data_model::entities::{Field, FieldType}; pub struct FieldBuilder { field: Field, diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs index b192a1e118..080e3aaa60 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options.rs @@ -2,12 +2,12 @@ use crate::impl_from_and_to_type_option; use crate::services::row::StringifyCellData; use crate::services::util::*; -use bytes::Bytes; + use chrono::format::strftime::StrftimeItems; use chrono::NaiveDateTime; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; +use flowy_grid_data_model::entities::{Field, FieldType}; use rust_decimal::Decimal; use rusty_money::{ iso::{Currency, CNY, EUR, USD}, @@ -25,12 +25,12 @@ pub struct RichTextDescription { impl_from_and_to_type_option!(RichTextDescription, FieldType::RichText); impl StringifyCellData for RichTextDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - data.to_string() + fn str_from_cell_data(&self, data: String) -> String { + data } - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(AnyData::from_str(self.field_type(), s)) + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(s.to_owned()) } } @@ -43,16 +43,16 @@ pub struct CheckboxDescription { impl_from_and_to_type_option!(CheckboxDescription, FieldType::Checkbox); impl StringifyCellData for CheckboxDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - data.to_string() + fn str_from_cell_data(&self, data: String) -> String { + data } - fn str_to_cell_data(&self, s: &str) -> Result { + fn str_to_cell_data(&self, s: &str) -> Result { let s = match string_to_bool(s) { true => "1", false => "0", }; - Ok(AnyData::from_str(self.field_type(), s)) + Ok(s.to_owned()) } } @@ -89,30 +89,24 @@ impl DateDescription { } impl StringifyCellData for DateDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - match String::from_utf8(data.value) { - Ok(s) => match s.parse::() { - Ok(timestamp) => { - let native = NaiveDateTime::from_timestamp(timestamp, 0); - self.today_from_native(native) - } - Err(e) => { - tracing::debug!("DateDescription format {} fail. error: {:?}", s, e); - String::new() - } - }, + fn str_from_cell_data(&self, data: String) -> String { + match data.parse::() { + Ok(timestamp) => { + let native = NaiveDateTime::from_timestamp(timestamp, 0); + self.today_from_native(native) + } Err(e) => { - tracing::error!("DateDescription stringify any_data failed. {:?}", e); + tracing::debug!("DateDescription format {} fail. error: {:?}", data, e); String::new() } } } - fn str_to_cell_data(&self, s: &str) -> Result { + fn str_to_cell_data(&self, s: &str) -> Result { let timestamp = s .parse::() .map_err(|e| FlowyError::internal().context(format!("Parse {} to i64 failed: {}", s, e)))?; - Ok(AnyData::from_str(self.field_type(), &format!("{}", timestamp))) + Ok(format!("{}", timestamp)) } } @@ -210,12 +204,12 @@ pub struct SingleSelectDescription { impl_from_and_to_type_option!(SingleSelectDescription, FieldType::SingleSelect); impl StringifyCellData for SingleSelectDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - data.to_string() + fn str_from_cell_data(&self, data: String) -> String { + data } - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(AnyData::from_str(self.field_type(), s)) + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(s.to_owned()) } } @@ -230,12 +224,12 @@ pub struct MultiSelectDescription { } impl_from_and_to_type_option!(MultiSelectDescription, FieldType::MultiSelect); impl StringifyCellData for MultiSelectDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - data.to_string() + fn str_from_cell_data(&self, data: String) -> String { + data } - fn str_to_cell_data(&self, s: &str) -> Result { - Ok(AnyData::from_str(self.field_type(), s)) + fn str_to_cell_data(&self, s: &str) -> Result { + Ok(s.to_owned()) } } @@ -322,24 +316,17 @@ impl NumberDescription { } impl StringifyCellData for NumberDescription { - fn str_from_cell_data(&self, data: AnyData) -> String { - match String::from_utf8(data.value) { - Ok(s) => match self.money_from_str(&s) { - Some(money_str) => money_str, - None => String::default(), - }, - Err(e) => { - tracing::error!("NumberDescription stringify any_data failed. {:?}", e); - String::new() - } + fn str_from_cell_data(&self, data: String) -> String { + match self.money_from_str(&data) { + Some(money_str) => money_str, + None => String::default(), } } - fn str_to_cell_data(&self, s: &str) -> Result { + fn str_to_cell_data(&self, s: &str) -> Result { let strip_symbol_money = strip_money_symbol(s); let decimal = Decimal::from_str(&strip_symbol_money).map_err(|err| FlowyError::internal().context(err))?; - let money_str = decimal.to_string(); - Ok(AnyData::from_str(self.field_type(), &money_str)) + Ok(decimal.to_string()) } } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index 4b7250079e..63defcf76b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,7 +1,7 @@ use crate::manager::GridUser; use crate::services::kv_persistence::{GridKVPersistence, KVTransaction}; -use crate::services::grid_meta_editor::{ClientGridBlockMetaEditor, GridBlockMetaEditorManager}; +use crate::services::grid_meta_editor::GridBlockMetaEditorManager; use bytes::Bytes; use dashmap::DashMap; use flowy_collaboration::client_grid::{GridChange, GridMetaPad}; @@ -9,13 +9,10 @@ use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::entities::{ - Field, FieldChangeset, Grid, GridBlock, GridBlockChangeset, RepeatedField, RepeatedFieldOrder, RepeatedRow, - RepeatedRowOrder, Row, -}; -use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; -use flowy_sync::{ - RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, + Field, FieldChangeset, Grid, GridBlock, GridBlockChangeset, RepeatedFieldOrder, RepeatedRowOrder, Row, }; + +use flowy_sync::{RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder}; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; use std::sync::Arc; @@ -83,23 +80,29 @@ impl ClientGridEditor { pub async fn create_row(&self) -> FlowyResult<()> { let fields = self.grid_meta_pad.read().await.get_fields(None)?; - match self.grid_meta_pad.read().await.get_blocks().last() { + let grid_block = match self.grid_meta_pad.read().await.get_blocks().last() { None => Err(FlowyError::internal().context("There is no grid block in this grid")), - Some(grid_block) => { - let row_count = self.block_meta_manager.create_row(fields, grid_block).await?; - let change = GridBlockChangeset::from_row_count(&grid_block.id, row_count); - let _ = self.update_block(change).await?; - Ok(()) - } - } + Some(grid_block) => Ok(grid_block.clone()), + }?; + + let row_count = self.block_meta_manager.create_row(fields, &grid_block).await?; + let change = GridBlockChangeset::from_row_count(&grid_block.id, row_count); + let _ = self.update_block(change).await?; + Ok(()) } - pub async fn get_rows(&self, row_orders: Option) -> FlowyResult> { + pub async fn get_rows(&self, row_orders: RepeatedRowOrder) -> FlowyResult> { let fields = self.grid_meta_pad.read().await.get_fields(None)?; let rows = self.block_meta_manager.get_rows(fields, row_orders).await?; Ok(rows) } + pub async fn get_all_rows(&self) -> FlowyResult> { + let fields = self.grid_meta_pad.read().await.get_fields(None)?; + let grid_blocks = self.grid_meta_pad.read().await.get_blocks(); + self.block_meta_manager.get_all_rows(grid_blocks, fields).await + } + pub async fn delete_rows(&self, row_orders: Option) -> FlowyResult<()> { let row_counts = self.block_meta_manager.delete_rows(row_orders).await?; for (block_id, row_count) in row_counts { diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs index 5358b4cde5..211af6d340 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_meta_editor.rs @@ -1,22 +1,20 @@ use crate::manager::GridUser; -use crate::services::row::{make_row_ids_per_block, make_rows, sort_rows, RowBuilder}; +use crate::services::row::{make_row_by_row_id, make_row_ids_per_block, make_rows, RowBuilder}; use bytes::Bytes; -use dashmap::mapref::one::Ref; + use dashmap::DashMap; use flowy_collaboration::client_grid::{GridBlockMetaChange, GridBlockMetaPad}; use flowy_collaboration::entities::revision::Revision; use flowy_collaboration::util::make_delta_from_revisions; use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{ - Field, GridBlock, RepeatedRow, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset, -}; +use flowy_grid_data_model::entities::{Field, GridBlock, RepeatedRowOrder, Row, RowMeta, RowMetaChangeset}; use flowy_sync::disk::SQLiteGridBlockMetaRevisionPersistence; use flowy_sync::{ RevisionCloudService, RevisionCompactor, RevisionManager, RevisionObjectBuilder, RevisionPersistence, }; use lib_infra::future::FutureResult; use lib_ot::core::PlainTextAttributes; -use lib_sqlite::ConnectionPool; + use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLock; @@ -52,32 +50,34 @@ impl GridBlockMetaEditorManager { editor.create_row(row).await } - pub(crate) async fn delete_rows(&self, row_orders: Option) -> FlowyResult> { + pub(crate) async fn delete_rows(&self, _row_orders: Option) -> FlowyResult> { Ok(vec![("".to_owned(), 2)]) } - pub(crate) async fn get_rows( - &self, - fields: Vec, - row_orders: Option, - ) -> FlowyResult> { - match row_orders { - None => { - let rows = vec![]; - Ok(rows) - } - Some(row_orders) => { - let row_ids_per_blocks = make_row_ids_per_block(&row_orders); - let mut rows = vec![]; - for row_ids_per_block in row_ids_per_blocks { - let editor = self.get_editor(&row_ids_per_block.block_id).await?; - let row_metas = editor.get_rows(row_ids_per_block.row_ids).await?; - rows.extend(make_rows(&fields, row_metas)); - } - sort_rows(&mut rows, row_orders); - Ok(rows) - } + pub(crate) async fn get_all_rows(&self, grid_blocks: Vec, fields: Vec) -> FlowyResult> { + let mut rows = vec![]; + for grid_block in grid_blocks { + let editor = self.get_editor(&grid_block.id).await?; + let row_metas = editor.get_rows(None).await?; + rows.extend(make_rows(&fields, row_metas)); } + Ok(rows) + } + + pub(crate) async fn get_rows(&self, fields: Vec, row_orders: RepeatedRowOrder) -> FlowyResult> { + let row_ids_per_blocks = make_row_ids_per_block(&row_orders); + let mut row_map: HashMap = HashMap::new(); + for row_ids_per_block in row_ids_per_blocks { + let editor = self.get_editor(&row_ids_per_block.block_id).await?; + let row_metas = editor.get_rows(Some(row_ids_per_block.row_ids)).await?; + row_map.extend(make_row_by_row_id(&fields, row_metas)); + } + + let rows = row_orders + .iter() + .flat_map(|row_order| row_map.remove(&row_order.row_id)) + .collect::>(); + Ok(rows) } } @@ -158,9 +158,14 @@ impl ClientGridBlockMetaEditor { Ok(()) } - pub async fn get_rows(&self, row_ids: Vec) -> FlowyResult> { - let rows = self.meta_pad.read().await.get_rows(row_ids)?; - Ok(rows) + pub async fn get_rows(&self, row_ids: Option>) -> FlowyResult> { + match row_ids { + None => Ok(self.meta_pad.read().await.all_rows()), + Some(row_ids) => { + let rows = self.meta_pad.read().await.get_rows(row_ids)?; + Ok(rows) + } + } } async fn modify(&self, f: F) -> FlowyResult<()> diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs index a75506e339..cd68038b9c 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_stringify.rs @@ -1,15 +1,15 @@ use crate::services::field::*; -use crate::services::util::*; + use flowy_error::FlowyError; -use flowy_grid_data_model::entities::{AnyData, Field, FieldType}; +use flowy_grid_data_model::entities::{Field, FieldType}; pub trait StringifyCellData { - fn str_from_cell_data(&self, data: AnyData) -> String; - fn str_to_cell_data(&self, s: &str) -> Result; + fn str_from_cell_data(&self, data: String) -> String; + fn str_to_cell_data(&self, s: &str) -> Result; } #[allow(dead_code)] -pub fn stringify_serialize(field: &Field, s: &str) -> Result { +pub fn stringify_serialize(field: &Field, s: &str) -> Result { match field.field_type { FieldType::RichText => RichTextDescription::from(field).str_to_cell_data(s), FieldType::Number => NumberDescription::from(field).str_to_cell_data(s), @@ -20,8 +20,8 @@ pub fn stringify_serialize(field: &Field, s: &str) -> Result Result { - let _ = check_type_id(&data, field)?; +pub(crate) fn stringify_deserialize(data: String, field: &Field) -> Result { + // let _ = check_type_id(&data, field)?; let s = match field.field_type { FieldType::RichText => RichTextDescription::from(field).str_from_cell_data(data), FieldType::Number => NumberDescription::from(field).str_from_cell_data(data), diff --git a/frontend/rust-lib/flowy-grid/src/services/row/mod.rs b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs index baac627e00..993e3401e3 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/mod.rs @@ -4,4 +4,4 @@ mod row_loader; pub use cell_stringify::*; pub use row_builder::*; -pub use row_loader::*; +pub(crate) use row_loader::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs index f9092a5d89..705871ad93 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_loader.rs @@ -1,4 +1,6 @@ -use flowy_grid_data_model::entities::{Field, RepeatedRowOrder, Row, RowMeta}; +use crate::services::row::stringify_deserialize; +use flowy_grid_data_model::entities::{Cell, CellMeta, Field, RepeatedRowOrder, Row, RowMeta}; +use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; pub(crate) struct RowIdsPerBlock { @@ -19,50 +21,67 @@ pub(crate) fn make_row_ids_per_block(row_orders: &RepeatedRowOrder) -> Vec>() } -pub(crate) fn sort_rows(rows: &mut Vec, row_orders: RepeatedRowOrder) { - todo!() +pub(crate) fn make_rows(fields: &Vec, row_metas: Vec) -> Vec { + let field_map = fields + .iter() + .map(|field| (&field.id, field)) + .collect::>(); + + let make_row = |row_meta: RowMeta| { + let cell_by_field_id = row_meta + .cell_by_field_id + .into_par_iter() + .flat_map(|(field_id, raw_cell)| make_cell(&field_map, field_id, raw_cell)) + .collect::>(); + + Row { + id: row_meta.id.clone(), + cell_by_field_id, + height: row_meta.height, + } + }; + + row_metas.into_iter().map(make_row).collect::>() } -pub(crate) fn make_rows(fields: &Vec, rows: Vec) -> Vec { - // let make_cell = |field_id: String, raw_cell: CellMeta| { - // let some_field = self.field_map.get(&field_id); - // if some_field.is_none() { - // tracing::error!("Can't find the field with {}", field_id); - // return None; - // } - // self.cell_map.insert(raw_cell.id.clone(), raw_cell.clone()); - // - // let field = some_field.unwrap(); - // match stringify_deserialize(raw_cell.data, field.value()) { - // Ok(content) => { - // let cell = Cell { - // id: raw_cell.id, - // field_id: field_id.clone(), - // content, - // }; - // Some((field_id, cell)) - // } - // Err(_) => None, - // } - // }; - // - // let rows = row_metas - // .into_par_iter() - // .map(|row_meta| { - // let mut row = Row { - // id: row_meta.id.clone(), - // cell_by_field_id: Default::default(), - // height: row_meta.height, - // }; - // row.cell_by_field_id = row_meta - // .cell_by_field_id - // .into_par_iter() - // .flat_map(|(field_id, raw_cell)| make_cell(field_id, raw_cell)) - // .collect::>(); - // row - // }) - // .collect::>(); - // - // Ok(rows.into()) - todo!() +#[inline(always)] +fn make_cell(field_map: &HashMap<&String, &Field>, field_id: String, raw_cell: CellMeta) -> Option<(String, Cell)> { + let field = field_map.get(&field_id)?; + match stringify_deserialize(raw_cell.data, field) { + Ok(content) => { + let cell = Cell::new(&field_id, content); + Some((field_id, cell)) + } + Err(e) => { + tracing::error!("{}", e); + None + } + } +} + +pub(crate) fn make_row_by_row_id(fields: &Vec, row_metas: Vec) -> HashMap { + let field_map = fields + .iter() + .map(|field| (&field.id, field)) + .collect::>(); + + let make_row = |row_meta: RowMeta| { + let cell_by_field_id = row_meta + .cell_by_field_id + .into_par_iter() + .flat_map(|(field_id, raw_cell)| make_cell(&field_map, field_id, raw_cell)) + .collect::>(); + + let row = Row { + id: row_meta.id.clone(), + cell_by_field_id, + height: row_meta.height, + }; + (row.id.clone(), row) + }; + + row_metas + .into_par_iter() + .map(make_row) + .collect::>() } diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index 8cf876a052..ef6060837e 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -1,6 +1,6 @@ use crate::services::field::*; use flowy_collaboration::client_grid::{BuildGridInfo, GridBuilder}; -use flowy_grid_data_model::entities::{Field, FieldType}; +use flowy_grid_data_model::entities::FieldType; pub fn make_default_grid(grid_id: &str) -> BuildGridInfo { let text_field = FieldBuilder::new(RichTextTypeOptionsBuilder::new()) diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs index 42af2ef4c4..410e7638a5 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs @@ -169,6 +169,6 @@ async fn grid_update_block() { #[tokio::test] async fn grid_create_row() { - let scripts = vec![AssertRowCount(2), CreateRow, CreateRow, CreateRow, AssertRowCount(5)]; + let scripts = vec![AssertRowCount(3), CreateRow, CreateRow, AssertRowCount(5)]; GridEditorTest::new().await.run_scripts(scripts).await; } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/script.rs index 277cd6b4da..278981dab3 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/script.rs @@ -1,8 +1,8 @@ use flowy_grid::services::field::*; use flowy_grid::services::grid_editor::{ClientGridEditor, GridPadBuilder}; -use flowy_grid_data_model::entities::{AnyData, Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset}; +use flowy_grid_data_model::entities::{Field, FieldChangeset, FieldType, GridBlock, GridBlockChangeset}; use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS; -use flowy_test::event_builder::FolderEventBuilder; + use flowy_test::helper::ViewTest; use flowy_test::FlowySDKTest; use std::sync::Arc; @@ -89,7 +89,7 @@ impl GridEditorTest { self.editor.create_row().await.unwrap(); } EditorScript::AssertRowCount(count) => { - assert_eq!(self.editor.get_rows(None).await.unwrap().len(), count); + assert_eq!(self.editor.get_all_rows().await.unwrap().len(), count); } EditorScript::AssertGridMetaPad => { sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await; diff --git a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs index b63c667cbd..790f9f3cfa 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/block_pad.rs @@ -1,5 +1,5 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; -use crate::errors::{internal_error, CollaborateError, CollaborateResult}; +use crate::errors::{CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; use flowy_grid_data_model::entities::{GridBlockMeta, RowMeta, RowMetaChangeset}; use lib_infra::uuid; @@ -69,6 +69,10 @@ impl GridBlockMetaPad { .collect::>()) } + pub fn all_rows(&self) -> Vec { + self.rows.iter().map(|row| (**row).clone()).collect::>() + } + pub fn number_of_rows(&self) -> i32 { self.rows.len() as i32 } diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs index 9ba6cc7ff5..b34f55b39b 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_builder.rs @@ -1,6 +1,6 @@ use crate::client_grid::{make_block_meta_delta, make_grid_delta, GridBlockMetaDelta, GridMetaDelta}; use crate::errors::{CollaborateError, CollaborateResult}; -use flowy_grid_data_model::entities::{Field, FieldType, GridBlock, GridBlockMeta, GridMeta, RowMeta}; +use flowy_grid_data_model::entities::{Field, GridBlock, GridBlockMeta, GridMeta, RowMeta}; pub struct GridBuilder { grid_id: String, diff --git a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs index 304919a310..89d2145e17 100644 --- a/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs +++ b/shared-lib/flowy-collaboration/src/client_grid/grid_pad.rs @@ -2,7 +2,7 @@ use crate::entities::revision::{md5, RepeatedRevision, Revision}; use crate::errors::{internal_error, CollaborateError, CollaborateResult}; use crate::util::{cal_diff, make_delta_from_revisions}; use flowy_grid_data_model::entities::{ - Field, FieldChangeset, GridBlock, GridBlockChangeset, GridMeta, RepeatedField, RepeatedFieldOrder, + Field, FieldChangeset, GridBlock, GridBlockChangeset, GridMeta, RepeatedFieldOrder, }; use lib_infra::uuid; use lib_ot::core::{OperationTransformable, PlainTextAttributes, PlainTextDelta, PlainTextDeltaBuilder}; @@ -58,7 +58,7 @@ impl GridMetaPad { pub fn get_fields(&self, field_orders: Option) -> CollaborateResult> { match field_orders { - None => Ok(self.grid_meta.fields.clone().into()), + None => Ok(self.grid_meta.fields.clone()), Some(field_orders) => { let field_by_field_id = self .grid_meta @@ -127,7 +127,7 @@ impl GridMetaPad { pub fn create_block(&mut self, block: GridBlock) -> CollaborateResult> { self.modify_grid(|grid| { - if grid.blocks.iter().find(|b| b.id == block.id).is_some() { + if grid.blocks.iter().any(|b| b.id == block.id) { tracing::warn!("Duplicate grid block"); Ok(None) } else { diff --git a/shared-lib/flowy-grid-data-model/src/entities/grid.rs b/shared-lib/flowy-grid-data-model/src/entities/grid.rs index d2bf2173f3..ef84bfe104 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/grid.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/grid.rs @@ -123,6 +123,15 @@ pub struct Cell { pub content: String, } +impl Cell { + pub fn new(field_id: &str, content: String) -> Self { + Self { + field_id: field_id.to_owned(), + content, + } + } +} + #[derive(ProtoBuf, Default)] pub struct CreateGridPayload { #[pb(index = 1)] diff --git a/shared-lib/flowy-grid-data-model/src/entities/meta.rs b/shared-lib/flowy-grid-data-model/src/entities/meta.rs index 2813759448..dee0a2b21b 100644 --- a/shared-lib/flowy-grid-data-model/src/entities/meta.rs +++ b/shared-lib/flowy-grid-data-model/src/entities/meta.rs @@ -175,13 +175,13 @@ impl std::default::Default for FieldType { impl AsRef for FieldType { fn as_ref(&self) -> &FieldType { - &self + self } } -impl Into for &FieldType { - fn into(self) -> FieldType { - self.clone() +impl From<&FieldType> for FieldType { + fn from(field: &FieldType) -> Self { + field.clone() } }