refactor: cell data operation

This commit is contained in:
appflowy 2022-05-23 22:53:13 +08:00
parent 1ae0b188b1
commit 5b2b50dc9c
6 changed files with 80 additions and 64 deletions

View File

@ -43,14 +43,15 @@ impl_type_option!(CheckboxTypeOption, FieldType::Checkbox);
const YES: &str = "Yes";
const NO: &str = "No";
impl CellDataOperation for CheckboxTypeOption {
impl CellDataOperation<String> for CheckboxTypeOption {
fn decode_cell_data<T: Into<TypeOptionCellData>>(
&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<T: Into<CellContentChangeset>>(
&self,
changeset: T,
_cell_meta: Option<CellMeta>,
) -> Result<String, FlowyError> {
fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
where
C: Into<CellContentChangeset>,
{
let changeset = changeset.into();
let s = match string_to_bool(&changeset) {
true => YES,

View File

@ -135,10 +135,11 @@ impl DateTypeOption {
}
}
impl CellDataOperation for DateTypeOption {
impl CellDataOperation<DateCellDataSerde> for DateTypeOption {
fn decode_cell_data<T: Into<TypeOptionCellData>>(
&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<T: Into<CellContentChangeset>>(
&self,
changeset: T,
_cell_meta: Option<CellMeta>,
) -> Result<String, FlowyError> {
fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<DateCellDataSerde, FlowyError>
where
C: Into<CellContentChangeset>,
{
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<Self> {
serde_json::from_str::<DateCellDataSerde>(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(),

View File

@ -76,14 +76,15 @@ pub struct NumberTypeOption {
}
impl_type_option!(NumberTypeOption, FieldType::Number);
impl CellDataOperation for NumberTypeOption {
impl CellDataOperation<String> for NumberTypeOption {
fn decode_cell_data<T: Into<TypeOptionCellData>>(
&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<T: Into<CellContentChangeset>>(
&self,
changeset: T,
_cell_meta: Option<CellMeta>,
) -> Result<String, FlowyError> {
fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
where
C: Into<CellContentChangeset>,
{
let changeset = changeset.into();
let mut data = changeset.trim().to_string();

View File

@ -95,14 +95,15 @@ impl SelectOptionOperation for SingleSelectTypeOption {
}
}
impl CellDataOperation for SingleSelectTypeOption {
impl CellDataOperation<String> for SingleSelectTypeOption {
fn decode_cell_data<T: Into<TypeOptionCellData>>(
&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<T: Into<CellContentChangeset>>(
&self,
changeset: T,
_cell_meta: Option<CellMeta>,
) -> Result<String, FlowyError> {
fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
where
C: Into<CellContentChangeset>,
{
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<String> for MultiSelectTypeOption {
fn decode_cell_data<T: Into<TypeOptionCellData>>(
&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<T: Into<CellContentChangeset>>(
&self,
changeset: T,
cell_meta: Option<CellMeta>,
) -> Result<String, FlowyError> {
fn apply_changeset<T>(&self, changeset: T, cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
where
T: Into<CellContentChangeset>,
{
let content_changeset: SelectOptionCellContentChangeset = serde_json::from_str(&changeset.into())?;
let new_cell_data: String;
match cell_meta {

View File

@ -34,17 +34,18 @@ pub struct RichTextTypeOption {
}
impl_type_option!(RichTextTypeOption, FieldType::RichText);
impl CellDataOperation for RichTextTypeOption {
impl CellDataOperation<String> for RichTextTypeOption {
fn decode_cell_data<T: Into<TypeOptionCellData>>(
&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<T: Into<CellContentChangeset>>(
&self,
changeset: T,
_cell_meta: Option<CellMeta>,
) -> Result<String, FlowyError> {
fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
where
C: Into<CellContentChangeset>,
{
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)
}
}
}

View File

@ -5,17 +5,22 @@ use serde::{Deserialize, Serialize};
use std::fmt::Formatter;
use std::str::FromStr;
pub trait CellDataOperation {
fn decode_cell_data<T: Into<TypeOptionCellData>>(&self, data: T, field_meta: &FieldMeta) -> DecodedCellData;
fn apply_changeset<T: Into<CellContentChangeset>>(
pub trait CellDataOperation<D, CO: ToString> {
fn decode_cell_data<T: Into<TypeOptionCellData>>(
&self,
changeset: T,
data: T,
decoded_field_type: &FieldType,
field_meta: &FieldMeta,
) -> DecodedCellData;
fn apply_changeset<C: Into<CellContentChangeset>>(
&self,
changeset: C,
cell_meta: Option<CellMeta>,
) -> Result<String, FlowyError>;
) -> Result<CO, FlowyError>;
}
#[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<T: Into<CellContentChangeset>>(
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<T: TryInto<TypeOptionCellData>>(
field_type: &FieldType,
) -> Option<DecodedCellData> {
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::<RichTextTypeOption>(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::<NumberTypeOption>(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::<DateTypeOption>(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::<SingleSelectTypeOption>(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::<MultiSelectTypeOption>(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::<CheckboxTypeOption>(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",