mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
refactor: cell data operation
This commit is contained in:
parent
1ae0b188b1
commit
5b2b50dc9c
@ -43,14 +43,15 @@ impl_type_option!(CheckboxTypeOption, FieldType::Checkbox);
|
|||||||
const YES: &str = "Yes";
|
const YES: &str = "Yes";
|
||||||
const NO: &str = "No";
|
const NO: &str = "No";
|
||||||
|
|
||||||
impl CellDataOperation for CheckboxTypeOption {
|
impl CellDataOperation<String> for CheckboxTypeOption {
|
||||||
fn decode_cell_data<T: Into<TypeOptionCellData>>(
|
fn decode_cell_data<T: Into<TypeOptionCellData>>(
|
||||||
&self,
|
&self,
|
||||||
type_option_cell_data: T,
|
type_option_cell_data: T,
|
||||||
|
decoded_field_type: &FieldType,
|
||||||
_field_meta: &FieldMeta,
|
_field_meta: &FieldMeta,
|
||||||
) -> DecodedCellData {
|
) -> DecodedCellData {
|
||||||
let type_option_cell_data = type_option_cell_data.into();
|
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();
|
return DecodedCellData::default();
|
||||||
}
|
}
|
||||||
let cell_data = type_option_cell_data.data;
|
let cell_data = type_option_cell_data.data;
|
||||||
@ -61,11 +62,10 @@ impl CellDataOperation for CheckboxTypeOption {
|
|||||||
DecodedCellData::default()
|
DecodedCellData::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_changeset<T: Into<CellContentChangeset>>(
|
fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
|
||||||
&self,
|
where
|
||||||
changeset: T,
|
C: Into<CellContentChangeset>,
|
||||||
_cell_meta: Option<CellMeta>,
|
{
|
||||||
) -> Result<String, FlowyError> {
|
|
||||||
let changeset = changeset.into();
|
let changeset = changeset.into();
|
||||||
let s = match string_to_bool(&changeset) {
|
let s = match string_to_bool(&changeset) {
|
||||||
true => YES,
|
true => YES,
|
||||||
|
@ -135,10 +135,11 @@ impl DateTypeOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CellDataOperation for DateTypeOption {
|
impl CellDataOperation<DateCellDataSerde> for DateTypeOption {
|
||||||
fn decode_cell_data<T: Into<TypeOptionCellData>>(
|
fn decode_cell_data<T: Into<TypeOptionCellData>>(
|
||||||
&self,
|
&self,
|
||||||
type_option_cell_data: T,
|
type_option_cell_data: T,
|
||||||
|
decoded_field_type: &FieldType,
|
||||||
_field_meta: &FieldMeta,
|
_field_meta: &FieldMeta,
|
||||||
) -> DecodedCellData {
|
) -> DecodedCellData {
|
||||||
let type_option_cell_data = type_option_cell_data.into();
|
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.
|
// It happens when switching from one field to another.
|
||||||
// For example:
|
// For example:
|
||||||
// FieldType::RichText -> FieldType::DateTime, it will display empty content on the screen.
|
// 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();
|
return DecodedCellData::default();
|
||||||
}
|
}
|
||||||
match DateCellDataSerde::from_str(&type_option_cell_data.data) {
|
match DateCellDataSerde::from_str(&type_option_cell_data.data) {
|
||||||
@ -155,11 +156,10 @@ impl CellDataOperation for DateTypeOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_changeset<T: Into<CellContentChangeset>>(
|
fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<DateCellDataSerde, FlowyError>
|
||||||
&self,
|
where
|
||||||
changeset: T,
|
C: Into<CellContentChangeset>,
|
||||||
_cell_meta: Option<CellMeta>,
|
{
|
||||||
) -> Result<String, FlowyError> {
|
|
||||||
let content_changeset: DateCellContentChangeset = serde_json::from_str(&changeset.into())?;
|
let content_changeset: DateCellContentChangeset = serde_json::from_str(&changeset.into())?;
|
||||||
let cell_data = match content_changeset.date_timestamp() {
|
let cell_data = match content_changeset.date_timestamp() {
|
||||||
None => DateCellDataSerde::default(),
|
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 }
|
Self { timestamp, time }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_string(self) -> String {
|
|
||||||
serde_json::to_string(&self).unwrap_or("".to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_str(s: &str) -> FlowyResult<Self> {
|
fn from_str(s: &str) -> FlowyResult<Self> {
|
||||||
serde_json::from_str::<DateCellDataSerde>(s).map_err(internal_error)
|
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 {
|
fn default_time_str(time_format: &TimeFormat) -> String {
|
||||||
match time_format {
|
match time_format {
|
||||||
TimeFormat::TwelveHour => "12:00 AM".to_string(),
|
TimeFormat::TwelveHour => "12:00 AM".to_string(),
|
||||||
|
@ -76,14 +76,15 @@ pub struct NumberTypeOption {
|
|||||||
}
|
}
|
||||||
impl_type_option!(NumberTypeOption, FieldType::Number);
|
impl_type_option!(NumberTypeOption, FieldType::Number);
|
||||||
|
|
||||||
impl CellDataOperation for NumberTypeOption {
|
impl CellDataOperation<String> for NumberTypeOption {
|
||||||
fn decode_cell_data<T: Into<TypeOptionCellData>>(
|
fn decode_cell_data<T: Into<TypeOptionCellData>>(
|
||||||
&self,
|
&self,
|
||||||
type_option_cell_data: T,
|
type_option_cell_data: T,
|
||||||
|
decoded_field_type: &FieldType,
|
||||||
_field_meta: &FieldMeta,
|
_field_meta: &FieldMeta,
|
||||||
) -> DecodedCellData {
|
) -> DecodedCellData {
|
||||||
let type_option_cell_data = type_option_cell_data.into();
|
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();
|
return DecodedCellData::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,11 +112,10 @@ impl CellDataOperation for NumberTypeOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_changeset<T: Into<CellContentChangeset>>(
|
fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
|
||||||
&self,
|
where
|
||||||
changeset: T,
|
C: Into<CellContentChangeset>,
|
||||||
_cell_meta: Option<CellMeta>,
|
{
|
||||||
) -> Result<String, FlowyError> {
|
|
||||||
let changeset = changeset.into();
|
let changeset = changeset.into();
|
||||||
let mut data = changeset.trim().to_string();
|
let mut data = changeset.trim().to_string();
|
||||||
|
|
||||||
|
@ -95,14 +95,15 @@ impl SelectOptionOperation for SingleSelectTypeOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CellDataOperation for SingleSelectTypeOption {
|
impl CellDataOperation<String> for SingleSelectTypeOption {
|
||||||
fn decode_cell_data<T: Into<TypeOptionCellData>>(
|
fn decode_cell_data<T: Into<TypeOptionCellData>>(
|
||||||
&self,
|
&self,
|
||||||
type_option_cell_data: T,
|
type_option_cell_data: T,
|
||||||
|
decoded_field_type: &FieldType,
|
||||||
_field_meta: &FieldMeta,
|
_field_meta: &FieldMeta,
|
||||||
) -> DecodedCellData {
|
) -> DecodedCellData {
|
||||||
let type_option_cell_data = type_option_cell_data.into();
|
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();
|
return DecodedCellData::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,11 +117,10 @@ impl CellDataOperation for SingleSelectTypeOption {
|
|||||||
DecodedCellData::default()
|
DecodedCellData::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_changeset<T: Into<CellContentChangeset>>(
|
fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
|
||||||
&self,
|
where
|
||||||
changeset: T,
|
C: Into<CellContentChangeset>,
|
||||||
_cell_meta: Option<CellMeta>,
|
{
|
||||||
) -> Result<String, FlowyError> {
|
|
||||||
let changeset = changeset.into();
|
let changeset = changeset.into();
|
||||||
let select_option_changeset: SelectOptionCellContentChangeset = serde_json::from_str(&changeset)?;
|
let select_option_changeset: SelectOptionCellContentChangeset = serde_json::from_str(&changeset)?;
|
||||||
let new_cell_data: String;
|
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>>(
|
fn decode_cell_data<T: Into<TypeOptionCellData>>(
|
||||||
&self,
|
&self,
|
||||||
type_option_cell_data: T,
|
type_option_cell_data: T,
|
||||||
|
decoded_field_type: &FieldType,
|
||||||
_field_meta: &FieldMeta,
|
_field_meta: &FieldMeta,
|
||||||
) -> DecodedCellData {
|
) -> DecodedCellData {
|
||||||
let type_option_cell_data = type_option_cell_data.into();
|
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();
|
return DecodedCellData::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,11 +211,10 @@ impl CellDataOperation for MultiSelectTypeOption {
|
|||||||
DecodedCellData::from_content(content)
|
DecodedCellData::from_content(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_changeset<T: Into<CellContentChangeset>>(
|
fn apply_changeset<T>(&self, changeset: T, cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
|
||||||
&self,
|
where
|
||||||
changeset: T,
|
T: Into<CellContentChangeset>,
|
||||||
cell_meta: Option<CellMeta>,
|
{
|
||||||
) -> Result<String, FlowyError> {
|
|
||||||
let content_changeset: SelectOptionCellContentChangeset = serde_json::from_str(&changeset.into())?;
|
let content_changeset: SelectOptionCellContentChangeset = serde_json::from_str(&changeset.into())?;
|
||||||
let new_cell_data: String;
|
let new_cell_data: String;
|
||||||
match cell_meta {
|
match cell_meta {
|
||||||
|
@ -34,17 +34,18 @@ pub struct RichTextTypeOption {
|
|||||||
}
|
}
|
||||||
impl_type_option!(RichTextTypeOption, FieldType::RichText);
|
impl_type_option!(RichTextTypeOption, FieldType::RichText);
|
||||||
|
|
||||||
impl CellDataOperation for RichTextTypeOption {
|
impl CellDataOperation<String> for RichTextTypeOption {
|
||||||
fn decode_cell_data<T: Into<TypeOptionCellData>>(
|
fn decode_cell_data<T: Into<TypeOptionCellData>>(
|
||||||
&self,
|
&self,
|
||||||
type_option_cell_data: T,
|
type_option_cell_data: T,
|
||||||
|
decoded_field_type: &FieldType,
|
||||||
field_meta: &FieldMeta,
|
field_meta: &FieldMeta,
|
||||||
) -> DecodedCellData {
|
) -> DecodedCellData {
|
||||||
let type_option_cell_data = type_option_cell_data.into();
|
let type_option_cell_data = type_option_cell_data.into();
|
||||||
if type_option_cell_data.is_date()
|
if decoded_field_type.is_date()
|
||||||
|| type_option_cell_data.is_single_select()
|
|| decoded_field_type.is_single_select()
|
||||||
|| type_option_cell_data.is_multi_select()
|
|| decoded_field_type.is_multi_select()
|
||||||
|| type_option_cell_data.is_number()
|
|| decoded_field_type.is_number()
|
||||||
{
|
{
|
||||||
let field_type = type_option_cell_data.field_type.clone();
|
let field_type = type_option_cell_data.field_type.clone();
|
||||||
decode_cell_data(type_option_cell_data, field_meta, &field_type).unwrap_or_default()
|
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>>(
|
fn apply_changeset<C>(&self, changeset: C, _cell_meta: Option<CellMeta>) -> Result<String, FlowyError>
|
||||||
&self,
|
where
|
||||||
changeset: T,
|
C: Into<CellContentChangeset>,
|
||||||
_cell_meta: Option<CellMeta>,
|
{
|
||||||
) -> Result<String, FlowyError> {
|
|
||||||
let data = changeset.into();
|
let data = changeset.into();
|
||||||
if data.len() > 10000 {
|
if data.len() > 10000 {
|
||||||
Err(FlowyError::text_too_long().context("The len of the text should not be more than 10000"))
|
Err(FlowyError::text_too_long().context("The len of the text should not be more than 10000"))
|
||||||
} else {
|
} else {
|
||||||
Ok(data.to_string())
|
Ok(data.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,17 +5,22 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::fmt::Formatter;
|
use std::fmt::Formatter;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
pub trait CellDataOperation {
|
pub trait CellDataOperation<D, CO: ToString> {
|
||||||
fn decode_cell_data<T: Into<TypeOptionCellData>>(&self, data: T, field_meta: &FieldMeta) -> DecodedCellData;
|
fn decode_cell_data<T: Into<TypeOptionCellData>>(
|
||||||
fn apply_changeset<T: Into<CellContentChangeset>>(
|
|
||||||
&self,
|
&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>,
|
cell_meta: Option<CellMeta>,
|
||||||
) -> Result<String, FlowyError>;
|
) -> Result<CO, FlowyError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CellContentChangeset(String);
|
pub struct CellContentChangeset(pub String);
|
||||||
|
|
||||||
impl std::fmt::Display for CellContentChangeset {
|
impl std::fmt::Display for CellContentChangeset {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
@ -44,6 +49,12 @@ pub struct TypeOptionCellData {
|
|||||||
pub field_type: FieldType,
|
pub field_type: FieldType,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TypeOptionCellData {
|
||||||
|
pub fn split(self) -> (String, FieldType) {
|
||||||
|
(self.data, self.field_type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl std::str::FromStr for TypeOptionCellData {
|
impl std::str::FromStr for TypeOptionCellData {
|
||||||
type Err = FlowyError;
|
type Err = FlowyError;
|
||||||
|
|
||||||
@ -120,7 +131,9 @@ pub fn apply_cell_data_changeset<T: Into<CellContentChangeset>>(
|
|||||||
let s = match field_meta.field_type {
|
let s = match field_meta.field_type {
|
||||||
FieldType::RichText => RichTextTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
|
FieldType::RichText => RichTextTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
|
||||||
FieldType::Number => NumberTypeOption::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::SingleSelect => SingleSelectTypeOption::from(field_meta).apply_changeset(changeset, cell_meta),
|
||||||
FieldType::MultiSelect => MultiSelectTypeOption::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),
|
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,
|
field_type: &FieldType,
|
||||||
) -> Option<DecodedCellData> {
|
) -> Option<DecodedCellData> {
|
||||||
if let Ok(type_option_cell_data) = data.try_into() {
|
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 {
|
let s = match field_type {
|
||||||
FieldType::RichText => field_meta
|
FieldType::RichText => field_meta
|
||||||
.get_type_option_entry::<RichTextTypeOption>(field_type)?
|
.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
|
FieldType::Number => field_meta
|
||||||
.get_type_option_entry::<NumberTypeOption>(field_type)?
|
.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
|
FieldType::DateTime => field_meta
|
||||||
.get_type_option_entry::<DateTypeOption>(field_type)?
|
.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
|
FieldType::SingleSelect => field_meta
|
||||||
.get_type_option_entry::<SingleSelectTypeOption>(field_type)?
|
.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
|
FieldType::MultiSelect => field_meta
|
||||||
.get_type_option_entry::<MultiSelectTypeOption>(field_type)?
|
.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
|
FieldType::Checkbox => field_meta
|
||||||
.get_type_option_entry::<CheckboxTypeOption>(field_type)?
|
.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(
|
tracing::Span::current().record(
|
||||||
"content",
|
"content",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user