diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs index a3c084de03..111715ba6b 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option.rs @@ -43,14 +43,15 @@ impl_type_option!(CheckboxTypeOption, FieldType::Checkbox); const YES: &str = "Yes"; const NO: &str = "No"; -impl CellDataOperation for CheckboxTypeOption { +impl CellDataOperation for CheckboxTypeOption { fn decode_cell_data>( &self, type_option_cell_data: T, + decoded_field_type: &FieldType, _field_meta: &FieldMeta, ) -> DecodedCellData { let type_option_cell_data = type_option_cell_data.into(); - if !type_option_cell_data.is_checkbox() { + if !decoded_field_type.is_checkbox() { return DecodedCellData::default(); } let cell_data = type_option_cell_data.data; @@ -61,11 +62,10 @@ impl CellDataOperation for CheckboxTypeOption { DecodedCellData::default() } - fn apply_changeset>( - &self, - changeset: T, - _cell_meta: Option, - ) -> Result { + fn apply_changeset(&self, changeset: C, _cell_meta: Option) -> Result + where + C: Into, + { let changeset = changeset.into(); let s = match string_to_bool(&changeset) { true => YES, diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs index 3dcc1d81eb..62e4887746 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs @@ -135,10 +135,11 @@ impl DateTypeOption { } } -impl CellDataOperation for DateTypeOption { +impl CellDataOperation for DateTypeOption { fn decode_cell_data>( &self, type_option_cell_data: T, + decoded_field_type: &FieldType, _field_meta: &FieldMeta, ) -> DecodedCellData { let type_option_cell_data = type_option_cell_data.into(); @@ -146,7 +147,7 @@ impl CellDataOperation for DateTypeOption { // It happens when switching from one field to another. // For example: // FieldType::RichText -> FieldType::DateTime, it will display empty content on the screen. - if !type_option_cell_data.is_date() { + if !decoded_field_type.is_date() { return DecodedCellData::default(); } match DateCellDataSerde::from_str(&type_option_cell_data.data) { @@ -155,11 +156,10 @@ impl CellDataOperation for DateTypeOption { } } - fn apply_changeset>( - &self, - changeset: T, - _cell_meta: Option, - ) -> Result { + fn apply_changeset(&self, changeset: C, _cell_meta: Option) -> Result + where + C: Into, + { let content_changeset: DateCellContentChangeset = serde_json::from_str(&changeset.into())?; let cell_data = match content_changeset.date_timestamp() { None => DateCellDataSerde::default(), @@ -174,7 +174,7 @@ impl CellDataOperation for DateTypeOption { }, }; - Ok(cell_data.to_string()) + Ok(cell_data) } } @@ -316,15 +316,17 @@ impl DateCellDataSerde { Self { timestamp, time } } - fn to_string(self) -> String { - serde_json::to_string(&self).unwrap_or("".to_string()) - } - fn from_str(s: &str) -> FlowyResult { serde_json::from_str::(s).map_err(internal_error) } } +impl ToString for DateCellDataSerde { + fn to_string(&self) -> String { + serde_json::to_string(&self).unwrap_or("".to_string()) + } +} + fn default_time_str(time_format: &TimeFormat) -> String { match time_format { TimeFormat::TwelveHour => "12:00 AM".to_string(), diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs index 26f524b110..b97a3ca092 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs @@ -76,14 +76,15 @@ pub struct NumberTypeOption { } impl_type_option!(NumberTypeOption, FieldType::Number); -impl CellDataOperation for NumberTypeOption { +impl CellDataOperation for NumberTypeOption { fn decode_cell_data>( &self, type_option_cell_data: T, + decoded_field_type: &FieldType, _field_meta: &FieldMeta, ) -> DecodedCellData { let type_option_cell_data = type_option_cell_data.into(); - if type_option_cell_data.is_date() { + if decoded_field_type.is_date() { return DecodedCellData::default(); } @@ -111,11 +112,10 @@ impl CellDataOperation for NumberTypeOption { } } - fn apply_changeset>( - &self, - changeset: T, - _cell_meta: Option, - ) -> Result { + fn apply_changeset(&self, changeset: C, _cell_meta: Option) -> Result + where + C: Into, + { let changeset = changeset.into(); let mut data = changeset.trim().to_string(); diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs index 71aa697b6f..3d9cee701f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/selection_type_option.rs @@ -95,14 +95,15 @@ impl SelectOptionOperation for SingleSelectTypeOption { } } -impl CellDataOperation for SingleSelectTypeOption { +impl CellDataOperation for SingleSelectTypeOption { fn decode_cell_data>( &self, type_option_cell_data: T, + decoded_field_type: &FieldType, _field_meta: &FieldMeta, ) -> DecodedCellData { let type_option_cell_data = type_option_cell_data.into(); - if !type_option_cell_data.is_select_option() { + if !decoded_field_type.is_select_option() { return DecodedCellData::default(); } @@ -116,11 +117,10 @@ impl CellDataOperation for SingleSelectTypeOption { DecodedCellData::default() } - fn apply_changeset>( - &self, - changeset: T, - _cell_meta: Option, - ) -> Result { + fn apply_changeset(&self, changeset: C, _cell_meta: Option) -> Result + where + C: Into, + { let changeset = changeset.into(); let select_option_changeset: SelectOptionCellContentChangeset = serde_json::from_str(&changeset)?; let new_cell_data: String; @@ -187,14 +187,15 @@ impl SelectOptionOperation for MultiSelectTypeOption { } } -impl CellDataOperation for MultiSelectTypeOption { +impl CellDataOperation for MultiSelectTypeOption { fn decode_cell_data>( &self, type_option_cell_data: T, + decoded_field_type: &FieldType, _field_meta: &FieldMeta, ) -> DecodedCellData { let type_option_cell_data = type_option_cell_data.into(); - if !type_option_cell_data.is_select_option() { + if !decoded_field_type.is_select_option() { return DecodedCellData::default(); } @@ -210,11 +211,10 @@ impl CellDataOperation for MultiSelectTypeOption { DecodedCellData::from_content(content) } - fn apply_changeset>( - &self, - changeset: T, - cell_meta: Option, - ) -> Result { + fn apply_changeset(&self, changeset: T, cell_meta: Option) -> Result + where + T: Into, + { let content_changeset: SelectOptionCellContentChangeset = serde_json::from_str(&changeset.into())?; let new_cell_data: String; match cell_meta { diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs index f24af8328b..7cf4fc3d3e 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs @@ -34,17 +34,18 @@ pub struct RichTextTypeOption { } impl_type_option!(RichTextTypeOption, FieldType::RichText); -impl CellDataOperation for RichTextTypeOption { +impl CellDataOperation for RichTextTypeOption { fn decode_cell_data>( &self, type_option_cell_data: T, + decoded_field_type: &FieldType, field_meta: &FieldMeta, ) -> DecodedCellData { let type_option_cell_data = type_option_cell_data.into(); - if type_option_cell_data.is_date() - || type_option_cell_data.is_single_select() - || type_option_cell_data.is_multi_select() - || type_option_cell_data.is_number() + if decoded_field_type.is_date() + || decoded_field_type.is_single_select() + || decoded_field_type.is_multi_select() + || decoded_field_type.is_number() { let field_type = type_option_cell_data.field_type.clone(); decode_cell_data(type_option_cell_data, field_meta, &field_type).unwrap_or_default() @@ -53,16 +54,15 @@ impl CellDataOperation for RichTextTypeOption { } } - fn apply_changeset>( - &self, - changeset: T, - _cell_meta: Option, - ) -> Result { + fn apply_changeset(&self, changeset: C, _cell_meta: Option) -> Result + where + C: Into, + { let data = changeset.into(); if data.len() > 10000 { Err(FlowyError::text_too_long().context("The len of the text should not be more than 10000")) } else { - Ok(data.to_string()) + Ok(data.0) } } } diff --git a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs index 73513d29f8..2bb78a0bf0 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/cell_data_operation.rs @@ -5,17 +5,22 @@ use serde::{Deserialize, Serialize}; use std::fmt::Formatter; use std::str::FromStr; -pub trait CellDataOperation { - fn decode_cell_data>(&self, data: T, field_meta: &FieldMeta) -> DecodedCellData; - fn apply_changeset>( +pub trait CellDataOperation { + fn decode_cell_data>( &self, - changeset: T, + data: T, + decoded_field_type: &FieldType, + field_meta: &FieldMeta, + ) -> DecodedCellData; + fn apply_changeset>( + &self, + changeset: C, cell_meta: Option, - ) -> Result; + ) -> Result; } #[derive(Debug)] -pub struct CellContentChangeset(String); +pub struct CellContentChangeset(pub String); impl std::fmt::Display for CellContentChangeset { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { @@ -44,6 +49,12 @@ pub struct TypeOptionCellData { pub field_type: FieldType, } +impl TypeOptionCellData { + pub fn split(self) -> (String, FieldType) { + (self.data, self.field_type) + } +} + impl std::str::FromStr for TypeOptionCellData { type Err = FlowyError; @@ -120,7 +131,9 @@ pub fn apply_cell_data_changeset>( let s = match field_meta.field_type { FieldType::RichText => RichTextTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), FieldType::Number => NumberTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), - FieldType::DateTime => DateTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), + FieldType::DateTime => DateTypeOption::from(field_meta) + .apply_changeset(changeset, cell_meta) + .map(|data| data.to_string()), FieldType::SingleSelect => SingleSelectTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), FieldType::MultiSelect => MultiSelectTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), FieldType::Checkbox => CheckboxTypeOption::from(field_meta).apply_changeset(changeset, cell_meta), @@ -135,25 +148,26 @@ pub fn decode_cell_data>( field_type: &FieldType, ) -> Option { if let Ok(type_option_cell_data) = data.try_into() { + let (decoded_field_type, data) = &type_option_cell_data.split(); let s = match field_type { FieldType::RichText => field_meta .get_type_option_entry::(field_type)? - .decode_cell_data(type_option_cell_data, field_meta), + .decode_cell_data(type_option_cell_data, decoded_field_type, field_meta), FieldType::Number => field_meta .get_type_option_entry::(field_type)? - .decode_cell_data(type_option_cell_data, field_meta), + .decode_cell_data(type_option_cell_data, decoded_field_type, field_meta), FieldType::DateTime => field_meta .get_type_option_entry::(field_type)? - .decode_cell_data(type_option_cell_data, field_meta), + .decode_cell_data(type_option_cell_data, decoded_field_type, field_meta), FieldType::SingleSelect => field_meta .get_type_option_entry::(field_type)? - .decode_cell_data(type_option_cell_data, field_meta), + .decode_cell_data(type_option_cell_data, decoded_field_type, field_meta), FieldType::MultiSelect => field_meta .get_type_option_entry::(field_type)? - .decode_cell_data(type_option_cell_data, field_meta), + .decode_cell_data(type_option_cell_data, decoded_field_type, field_meta), FieldType::Checkbox => field_meta .get_type_option_entry::(field_type)? - .decode_cell_data(type_option_cell_data, field_meta), + .decode_cell_data(type_option_cell_data, decoded_field_type, field_meta), }; tracing::Span::current().record( "content",