mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
refactor: cell data parser
This commit is contained in:
parent
41989cf186
commit
4ec1e4024e
@ -1,6 +1,6 @@
|
|||||||
use crate::entities::{CellChangeset, CellIdentifier, CellIdentifierPayload, FieldType};
|
use crate::entities::{CellChangeset, CellIdentifier, CellIdentifierPayload, FieldType};
|
||||||
use crate::services::field::{MultiSelectTypeOption, SingleSelectTypeOption};
|
use crate::services::field::{MultiSelectTypeOption, SingleSelectTypeOption};
|
||||||
use crate::services::row::AnyCellData;
|
use crate::services::row::{AnyCellData, FromCellString};
|
||||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||||
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
|
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
|
||||||
use flowy_grid_data_model::parser::NotEmptyStr;
|
use flowy_grid_data_model::parser::NotEmptyStr;
|
||||||
@ -155,6 +155,15 @@ impl std::convert::TryFrom<AnyCellData> for SelectOptionIds {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromCellString for SelectOptionIds {
|
||||||
|
fn from_cell_str(s: &str) -> FlowyResult<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
Ok(Self::from(s.to_owned()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl std::convert::From<String> for SelectOptionIds {
|
impl std::convert::From<String> for SelectOptionIds {
|
||||||
fn from(s: String) -> Self {
|
fn from(s: String) -> Self {
|
||||||
let ids = s
|
let ids = s
|
||||||
|
@ -2,7 +2,7 @@ use crate::entities::{FieldType, GridCheckboxFilter};
|
|||||||
use crate::impl_type_option;
|
use crate::impl_type_option;
|
||||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||||
use crate::services::row::{
|
use crate::services::row::{
|
||||||
AnyCellData, CellContentChangeset, CellDataOperation, CellFilterOperation, DecodedCellData,
|
AnyCellData, CellContentChangeset, CellData, CellDataOperation, CellFilterOperation, DecodedCellData,
|
||||||
};
|
};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use flowy_derive::ProtoBuf;
|
use flowy_derive::ProtoBuf;
|
||||||
@ -53,22 +53,19 @@ impl CellFilterOperation<GridCheckboxFilter> for CheckboxTypeOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CellDataOperation<String> for CheckboxTypeOption {
|
impl CellDataOperation<String> for CheckboxTypeOption {
|
||||||
fn decode_cell_data<T>(
|
fn decode_cell_data(
|
||||||
&self,
|
&self,
|
||||||
cell_data: T,
|
cell_data: CellData<String>,
|
||||||
decoded_field_type: &FieldType,
|
decoded_field_type: &FieldType,
|
||||||
_field_rev: &FieldRevision,
|
_field_rev: &FieldRevision,
|
||||||
) -> FlowyResult<DecodedCellData>
|
) -> FlowyResult<DecodedCellData> {
|
||||||
where
|
|
||||||
T: Into<String>,
|
|
||||||
{
|
|
||||||
if !decoded_field_type.is_checkbox() {
|
if !decoded_field_type.is_checkbox() {
|
||||||
return Ok(DecodedCellData::default());
|
return Ok(DecodedCellData::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
let encoded_data = cell_data.into();
|
let s: String = cell_data.try_into_inner()?;
|
||||||
if encoded_data == YES || encoded_data == NO {
|
if s == YES || s == NO {
|
||||||
return Ok(DecodedCellData::new(encoded_data));
|
return Ok(DecodedCellData::new(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(DecodedCellData::default())
|
Ok(DecodedCellData::default())
|
||||||
|
@ -3,7 +3,8 @@ use crate::entities::{CellIdentifier, CellIdentifierPayload};
|
|||||||
use crate::impl_type_option;
|
use crate::impl_type_option;
|
||||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||||
use crate::services::row::{
|
use crate::services::row::{
|
||||||
AnyCellData, CellContentChangeset, CellDataOperation, CellFilterOperation, DecodedCellData,
|
AnyCellData, CellContentChangeset, CellData, CellDataOperation, CellFilterOperation, DecodedCellData,
|
||||||
|
FromCellString,
|
||||||
};
|
};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use chrono::format::strftime::StrftimeItems;
|
use chrono::format::strftime::StrftimeItems;
|
||||||
@ -126,16 +127,13 @@ impl CellFilterOperation<GridDateFilter> for DateTypeOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CellDataOperation<String> for DateTypeOption {
|
impl CellDataOperation<TimestampParser> for DateTypeOption {
|
||||||
fn decode_cell_data<T>(
|
fn decode_cell_data(
|
||||||
&self,
|
&self,
|
||||||
cell_data: T,
|
cell_data: CellData<TimestampParser>,
|
||||||
decoded_field_type: &FieldType,
|
decoded_field_type: &FieldType,
|
||||||
_field_rev: &FieldRevision,
|
_field_rev: &FieldRevision,
|
||||||
) -> FlowyResult<DecodedCellData>
|
) -> FlowyResult<DecodedCellData> {
|
||||||
where
|
|
||||||
T: Into<String>,
|
|
||||||
{
|
|
||||||
// Return default data if the type_option_cell_data is not FieldType::DateTime.
|
// Return default data if the type_option_cell_data is not FieldType::DateTime.
|
||||||
// It happens when switching from one field to another.
|
// It happens when switching from one field to another.
|
||||||
// For example:
|
// For example:
|
||||||
@ -143,9 +141,8 @@ impl CellDataOperation<String> for DateTypeOption {
|
|||||||
if !decoded_field_type.is_date() {
|
if !decoded_field_type.is_date() {
|
||||||
return Ok(DecodedCellData::default());
|
return Ok(DecodedCellData::default());
|
||||||
}
|
}
|
||||||
|
let timestamp = cell_data.try_into_inner()?;
|
||||||
let timestamp = cell_data.into().parse::<i64>().unwrap_or(0);
|
let date = self.today_desc_from_timestamp(timestamp.0);
|
||||||
let date = self.today_desc_from_timestamp(timestamp);
|
|
||||||
DecodedCellData::try_from_bytes(date)
|
DecodedCellData::try_from_bytes(date)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,6 +167,17 @@ impl CellDataOperation<String> for DateTypeOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct TimestampParser(i64);
|
||||||
|
|
||||||
|
impl FromCellString for TimestampParser {
|
||||||
|
fn from_cell_str(s: &str) -> FlowyResult<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
let num = s.parse::<i64>().unwrap_or(0);
|
||||||
|
Ok(TimestampParser(num))
|
||||||
|
}
|
||||||
|
}
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct DateTypeOptionBuilder(DateTypeOption);
|
pub struct DateTypeOptionBuilder(DateTypeOption);
|
||||||
impl_into_box_type_option_builder!(DateTypeOptionBuilder);
|
impl_into_box_type_option_builder!(DateTypeOptionBuilder);
|
||||||
|
@ -8,7 +8,7 @@ use crate::services::field::select_option::{
|
|||||||
use crate::services::field::type_options::util::get_cell_data;
|
use crate::services::field::type_options::util::get_cell_data;
|
||||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||||
use crate::services::row::{
|
use crate::services::row::{
|
||||||
AnyCellData, CellContentChangeset, CellDataOperation, CellFilterOperation, DecodedCellData,
|
AnyCellData, CellContentChangeset, CellData, CellDataOperation, CellFilterOperation, DecodedCellData,
|
||||||
};
|
};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use flowy_derive::ProtoBuf;
|
use flowy_derive::ProtoBuf;
|
||||||
@ -56,22 +56,18 @@ impl CellFilterOperation<GridSelectOptionFilter> for MultiSelectTypeOption {
|
|||||||
Ok(filter.apply(&selected_options))
|
Ok(filter.apply(&selected_options))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl CellDataOperation<String> for MultiSelectTypeOption {
|
impl CellDataOperation<SelectOptionIds> for MultiSelectTypeOption {
|
||||||
fn decode_cell_data<T>(
|
fn decode_cell_data(
|
||||||
&self,
|
&self,
|
||||||
cell_data: T,
|
cell_data: CellData<SelectOptionIds>,
|
||||||
decoded_field_type: &FieldType,
|
decoded_field_type: &FieldType,
|
||||||
_field_rev: &FieldRevision,
|
_field_rev: &FieldRevision,
|
||||||
) -> FlowyResult<DecodedCellData>
|
) -> FlowyResult<DecodedCellData> {
|
||||||
where
|
|
||||||
T: Into<String>,
|
|
||||||
{
|
|
||||||
if !decoded_field_type.is_select_option() {
|
if !decoded_field_type.is_select_option() {
|
||||||
return Ok(DecodedCellData::default());
|
return Ok(DecodedCellData::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
let encoded_data = cell_data.into();
|
let ids: SelectOptionIds = cell_data.try_into_inner()?;
|
||||||
let ids: SelectOptionIds = encoded_data.into();
|
|
||||||
let select_options = ids
|
let select_options = ids
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|option_id| self.options.iter().find(|option| &option.id == option_id).cloned())
|
.flat_map(|option_id| self.options.iter().find(|option| &option.id == option_id).cloned())
|
||||||
|
@ -5,7 +5,7 @@ use crate::services::field::number_currency::Currency;
|
|||||||
use crate::services::field::type_options::number_type_option::format::*;
|
use crate::services::field::type_options::number_type_option::format::*;
|
||||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||||
use crate::services::row::{
|
use crate::services::row::{
|
||||||
AnyCellData, CellContentChangeset, CellDataOperation, CellFilterOperation, DecodedCellData,
|
AnyCellData, CellContentChangeset, CellData, CellDataOperation, CellFilterOperation, DecodedCellData,
|
||||||
};
|
};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use flowy_derive::ProtoBuf;
|
use flowy_derive::ProtoBuf;
|
||||||
@ -119,20 +119,17 @@ impl CellFilterOperation<GridNumberFilter> for NumberTypeOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CellDataOperation<String> for NumberTypeOption {
|
impl CellDataOperation<String> for NumberTypeOption {
|
||||||
fn decode_cell_data<T>(
|
fn decode_cell_data(
|
||||||
&self,
|
&self,
|
||||||
cell_data: T,
|
cell_data: CellData<String>,
|
||||||
decoded_field_type: &FieldType,
|
decoded_field_type: &FieldType,
|
||||||
_field_rev: &FieldRevision,
|
_field_rev: &FieldRevision,
|
||||||
) -> FlowyResult<DecodedCellData>
|
) -> FlowyResult<DecodedCellData> {
|
||||||
where
|
|
||||||
T: Into<String>,
|
|
||||||
{
|
|
||||||
if decoded_field_type.is_date() {
|
if decoded_field_type.is_date() {
|
||||||
return Ok(DecodedCellData::default());
|
return Ok(DecodedCellData::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
let cell_data = cell_data.into();
|
let cell_data: String = cell_data.try_into_inner()?;
|
||||||
match self.format_cell_data(&cell_data) {
|
match self.format_cell_data(&cell_data) {
|
||||||
Ok(num) => Ok(DecodedCellData::new(num.to_string())),
|
Ok(num) => Ok(DecodedCellData::new(num.to_string())),
|
||||||
Err(_) => Ok(DecodedCellData::default()),
|
Err(_) => Ok(DecodedCellData::default()),
|
||||||
|
@ -6,7 +6,7 @@ use crate::services::field::select_option::{
|
|||||||
};
|
};
|
||||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||||
use crate::services::row::{
|
use crate::services::row::{
|
||||||
AnyCellData, CellContentChangeset, CellDataOperation, CellFilterOperation, DecodedCellData,
|
AnyCellData, CellContentChangeset, CellData, CellDataOperation, CellFilterOperation, DecodedCellData,
|
||||||
};
|
};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use flowy_derive::ProtoBuf;
|
use flowy_derive::ProtoBuf;
|
||||||
@ -53,27 +53,22 @@ impl CellFilterOperation<GridSelectOptionFilter> for SingleSelectTypeOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CellDataOperation<String> for SingleSelectTypeOption {
|
impl CellDataOperation<SelectOptionIds> for SingleSelectTypeOption {
|
||||||
fn decode_cell_data<T>(
|
fn decode_cell_data(
|
||||||
&self,
|
&self,
|
||||||
cell_data: T,
|
cell_data: CellData<SelectOptionIds>,
|
||||||
decoded_field_type: &FieldType,
|
decoded_field_type: &FieldType,
|
||||||
_field_rev: &FieldRevision,
|
_field_rev: &FieldRevision,
|
||||||
) -> FlowyResult<DecodedCellData>
|
) -> FlowyResult<DecodedCellData> {
|
||||||
where
|
|
||||||
T: Into<String>,
|
|
||||||
{
|
|
||||||
if !decoded_field_type.is_select_option() {
|
if !decoded_field_type.is_select_option() {
|
||||||
return Ok(DecodedCellData::default());
|
return Ok(DecodedCellData::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
let encoded_data = cell_data.into();
|
let ids: SelectOptionIds = cell_data.try_into_inner()?;
|
||||||
let mut cell_data = SelectOptionCellData {
|
let mut cell_data = SelectOptionCellData {
|
||||||
options: self.options.clone(),
|
options: self.options.clone(),
|
||||||
select_options: vec![],
|
select_options: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
let ids: SelectOptionIds = encoded_data.into();
|
|
||||||
if let Some(option_id) = ids.first() {
|
if let Some(option_id) = ids.first() {
|
||||||
if let Some(option) = self.options.iter().find(|option| &option.id == option_id) {
|
if let Some(option) = self.options.iter().find(|option| &option.id == option_id) {
|
||||||
cell_data.select_options.push(option.clone());
|
cell_data.select_options.push(option.clone());
|
||||||
|
@ -2,7 +2,8 @@ use crate::entities::{FieldType, GridTextFilter};
|
|||||||
use crate::impl_type_option;
|
use crate::impl_type_option;
|
||||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||||
use crate::services::row::{
|
use crate::services::row::{
|
||||||
try_decode_cell_data, AnyCellData, CellContentChangeset, CellDataOperation, CellFilterOperation, DecodedCellData,
|
try_decode_cell_data, AnyCellData, CellContentChangeset, CellData, CellDataOperation, CellFilterOperation,
|
||||||
|
DecodedCellData,
|
||||||
};
|
};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use flowy_derive::ProtoBuf;
|
use flowy_derive::ProtoBuf;
|
||||||
@ -44,15 +45,12 @@ impl CellFilterOperation<GridTextFilter> for RichTextTypeOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CellDataOperation<String> for RichTextTypeOption {
|
impl CellDataOperation<String> for RichTextTypeOption {
|
||||||
fn decode_cell_data<T>(
|
fn decode_cell_data(
|
||||||
&self,
|
&self,
|
||||||
cell_data: T,
|
cell_data: CellData<String>,
|
||||||
decoded_field_type: &FieldType,
|
decoded_field_type: &FieldType,
|
||||||
field_rev: &FieldRevision,
|
field_rev: &FieldRevision,
|
||||||
) -> FlowyResult<DecodedCellData>
|
) -> FlowyResult<DecodedCellData> {
|
||||||
where
|
|
||||||
T: Into<String>,
|
|
||||||
{
|
|
||||||
if decoded_field_type.is_date()
|
if decoded_field_type.is_date()
|
||||||
|| decoded_field_type.is_single_select()
|
|| decoded_field_type.is_single_select()
|
||||||
|| decoded_field_type.is_multi_select()
|
|| decoded_field_type.is_multi_select()
|
||||||
@ -60,7 +58,7 @@ impl CellDataOperation<String> for RichTextTypeOption {
|
|||||||
{
|
{
|
||||||
try_decode_cell_data(cell_data.into(), field_rev, decoded_field_type, decoded_field_type)
|
try_decode_cell_data(cell_data.into(), field_rev, decoded_field_type, decoded_field_type)
|
||||||
} else {
|
} else {
|
||||||
let cell_data = cell_data.into();
|
let cell_data: String = cell_data.try_into_inner()?;
|
||||||
Ok(DecodedCellData::new(cell_data))
|
Ok(DecodedCellData::new(cell_data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,8 @@ use crate::entities::{FieldType, GridTextFilter};
|
|||||||
use crate::impl_type_option;
|
use crate::impl_type_option;
|
||||||
use crate::services::field::{BoxTypeOptionBuilder, TextCellData, TypeOptionBuilder};
|
use crate::services::field::{BoxTypeOptionBuilder, TextCellData, TypeOptionBuilder};
|
||||||
use crate::services::row::{
|
use crate::services::row::{
|
||||||
AnyCellData, CellContentChangeset, CellDataOperation, CellFilterOperation, DecodedCellData, Parser,
|
AnyCellData, CellContentChangeset, CellData, CellDataOperation, CellFilterOperation, DecodedCellData,
|
||||||
|
FromCellString,
|
||||||
};
|
};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use fancy_regex::Regex;
|
use fancy_regex::Regex;
|
||||||
@ -11,7 +12,6 @@ use flowy_error::{internal_error, FlowyError, FlowyResult};
|
|||||||
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
|
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct URLTypeOptionBuilder(URLTypeOption);
|
pub struct URLTypeOptionBuilder(URLTypeOption);
|
||||||
@ -46,20 +46,17 @@ impl CellFilterOperation<GridTextFilter> for URLTypeOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CellDataOperation<Parser<URLCellData>> for URLTypeOption {
|
impl CellDataOperation<URLCellData> for URLTypeOption {
|
||||||
fn decode_cell_data<T>(
|
fn decode_cell_data(
|
||||||
&self,
|
&self,
|
||||||
cell_data: T,
|
cell_data: CellData<URLCellData>,
|
||||||
decoded_field_type: &FieldType,
|
decoded_field_type: &FieldType,
|
||||||
_field_rev: &FieldRevision,
|
_field_rev: &FieldRevision,
|
||||||
) -> FlowyResult<DecodedCellData>
|
) -> FlowyResult<DecodedCellData> {
|
||||||
where
|
|
||||||
T: Into<Parser<URLCellData>>,
|
|
||||||
{
|
|
||||||
if !decoded_field_type.is_url() {
|
if !decoded_field_type.is_url() {
|
||||||
return Ok(DecodedCellData::default());
|
return Ok(DecodedCellData::default());
|
||||||
}
|
}
|
||||||
let cell_data = cell_data.into().try_into_inner()?;
|
let cell_data: URLCellData = cell_data.try_into_inner()?;
|
||||||
DecodedCellData::try_from_bytes(cell_data)
|
DecodedCellData::try_from_bytes(cell_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,10 +115,8 @@ impl URLCellData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for URLCellData {
|
impl FromCellString for URLCellData {
|
||||||
type Err = FlowyError;
|
fn from_cell_str(s: &str) -> FlowyResult<Self> {
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
serde_json::from_str::<URLCellData>(s).map_err(internal_error)
|
serde_json::from_str::<URLCellData>(s).map_err(internal_error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,7 +147,7 @@ mod tests {
|
|||||||
use crate::entities::FieldType;
|
use crate::entities::FieldType;
|
||||||
use crate::services::field::FieldBuilder;
|
use crate::services::field::FieldBuilder;
|
||||||
use crate::services::field::{URLCellData, URLTypeOption};
|
use crate::services::field::{URLCellData, URLTypeOption};
|
||||||
use crate::services::row::{CellDataOperation, Parser};
|
use crate::services::row::{CellData, CellDataOperation};
|
||||||
use flowy_grid_data_model::revision::FieldRevision;
|
use flowy_grid_data_model::revision::FieldRevision;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -201,7 +196,7 @@ mod tests {
|
|||||||
assert_eq!(expected_url.to_owned(), decode_cell_data.url);
|
assert_eq!(expected_url.to_owned(), decode_cell_data.url);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode_cell_data<T: Into<Parser<URLCellData>>>(
|
fn decode_cell_data<T: Into<CellData<URLCellData>>>(
|
||||||
encoded_data: T,
|
encoded_data: T,
|
||||||
type_option: &URLTypeOption,
|
type_option: &URLTypeOption,
|
||||||
field_rev: &FieldRevision,
|
field_rev: &FieldRevision,
|
||||||
|
@ -14,14 +14,12 @@ pub trait CellFilterOperation<T> {
|
|||||||
pub trait CellDataOperation<D> {
|
pub trait CellDataOperation<D> {
|
||||||
/// The cell_data is able to parse into the specific data that was impl the From<String> trait.
|
/// The cell_data is able to parse into the specific data that was impl the From<String> trait.
|
||||||
/// D will be URLCellData, DateCellData. etc.
|
/// D will be URLCellData, DateCellData. etc.
|
||||||
fn decode_cell_data<T>(
|
fn decode_cell_data(
|
||||||
&self,
|
&self,
|
||||||
cell_data: T,
|
cell_data: CellData<D>,
|
||||||
decoded_field_type: &FieldType,
|
decoded_field_type: &FieldType,
|
||||||
field_rev: &FieldRevision,
|
field_rev: &FieldRevision,
|
||||||
) -> FlowyResult<DecodedCellData>
|
) -> FlowyResult<DecodedCellData>;
|
||||||
where
|
|
||||||
T: Into<D>;
|
|
||||||
|
|
||||||
fn apply_changeset<C: Into<CellContentChangeset>>(
|
fn apply_changeset<C: Into<CellContentChangeset>>(
|
||||||
&self,
|
&self,
|
||||||
@ -178,7 +176,7 @@ pub fn decode_any_cell_data<T: TryInto<AnyCellData>>(data: T, field_rev: &FieldR
|
|||||||
if let Ok(any_cell_data) = data.try_into() {
|
if let Ok(any_cell_data) = data.try_into() {
|
||||||
let AnyCellData { cell_data, field_type } = any_cell_data;
|
let AnyCellData { cell_data, field_type } = any_cell_data;
|
||||||
let to_field_type = field_rev.field_type_rev.into();
|
let to_field_type = field_rev.field_type_rev.into();
|
||||||
match try_decode_cell_data(cell_data, field_rev, &field_type, &to_field_type) {
|
match try_decode_cell_data(CellData(Some(cell_data)), field_rev, &field_type, &to_field_type) {
|
||||||
Ok(cell_data) => cell_data,
|
Ok(cell_data) => cell_data,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::error!("Decode cell data failed, {:?}", e);
|
tracing::error!("Decode cell data failed, {:?}", e);
|
||||||
@ -192,35 +190,36 @@ pub fn decode_any_cell_data<T: TryInto<AnyCellData>>(data: T, field_rev: &FieldR
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_decode_cell_data(
|
pub fn try_decode_cell_data(
|
||||||
cell_data: String,
|
cell_data: CellData<String>,
|
||||||
field_rev: &FieldRevision,
|
field_rev: &FieldRevision,
|
||||||
s_field_type: &FieldType,
|
s_field_type: &FieldType,
|
||||||
t_field_type: &FieldType,
|
t_field_type: &FieldType,
|
||||||
) -> FlowyResult<DecodedCellData> {
|
) -> FlowyResult<DecodedCellData> {
|
||||||
|
let cell_data = cell_data.try_into_inner()?;
|
||||||
let get_cell_data = || {
|
let get_cell_data = || {
|
||||||
let field_type: FieldTypeRevision = t_field_type.into();
|
let field_type: FieldTypeRevision = t_field_type.into();
|
||||||
let data = match t_field_type {
|
let data = match t_field_type {
|
||||||
FieldType::RichText => field_rev
|
FieldType::RichText => field_rev
|
||||||
.get_type_option_entry::<RichTextTypeOption>(field_type)?
|
.get_type_option_entry::<RichTextTypeOption>(field_type)?
|
||||||
.decode_cell_data(cell_data, s_field_type, field_rev),
|
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
||||||
FieldType::Number => field_rev
|
FieldType::Number => field_rev
|
||||||
.get_type_option_entry::<NumberTypeOption>(field_type)?
|
.get_type_option_entry::<NumberTypeOption>(field_type)?
|
||||||
.decode_cell_data(cell_data, s_field_type, field_rev),
|
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
||||||
FieldType::DateTime => field_rev
|
FieldType::DateTime => field_rev
|
||||||
.get_type_option_entry::<DateTypeOption>(field_type)?
|
.get_type_option_entry::<DateTypeOption>(field_type)?
|
||||||
.decode_cell_data(cell_data, s_field_type, field_rev),
|
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
||||||
FieldType::SingleSelect => field_rev
|
FieldType::SingleSelect => field_rev
|
||||||
.get_type_option_entry::<SingleSelectTypeOption>(field_type)?
|
.get_type_option_entry::<SingleSelectTypeOption>(field_type)?
|
||||||
.decode_cell_data(cell_data, s_field_type, field_rev),
|
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
||||||
FieldType::MultiSelect => field_rev
|
FieldType::MultiSelect => field_rev
|
||||||
.get_type_option_entry::<MultiSelectTypeOption>(field_type)?
|
.get_type_option_entry::<MultiSelectTypeOption>(field_type)?
|
||||||
.decode_cell_data(cell_data, s_field_type, field_rev),
|
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
||||||
FieldType::Checkbox => field_rev
|
FieldType::Checkbox => field_rev
|
||||||
.get_type_option_entry::<CheckboxTypeOption>(field_type)?
|
.get_type_option_entry::<CheckboxTypeOption>(field_type)?
|
||||||
.decode_cell_data(cell_data, s_field_type, field_rev),
|
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
||||||
FieldType::URL => field_rev
|
FieldType::URL => field_rev
|
||||||
.get_type_option_entry::<URLTypeOption>(field_type)?
|
.get_type_option_entry::<URLTypeOption>(field_type)?
|
||||||
.decode_cell_data(cell_data, s_field_type, field_rev),
|
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
||||||
};
|
};
|
||||||
Some(data)
|
Some(data)
|
||||||
};
|
};
|
||||||
@ -235,9 +234,15 @@ pub fn try_decode_cell_data(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct Parser<T>(pub Option<T>);
|
pub trait FromCellString {
|
||||||
|
fn from_cell_str(s: &str) -> FlowyResult<Self>
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Parser<T> {
|
pub struct CellData<T>(pub Option<T>);
|
||||||
|
|
||||||
|
impl<T> CellData<T> {
|
||||||
pub fn try_into_inner(self) -> FlowyResult<T> {
|
pub fn try_into_inner(self) -> FlowyResult<T> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
None => Err(ErrorCode::InvalidData.into()),
|
None => Err(ErrorCode::InvalidData.into()),
|
||||||
@ -246,21 +251,33 @@ impl<T> Parser<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> std::convert::From<String> for Parser<T>
|
impl<T> std::convert::From<String> for CellData<T>
|
||||||
where
|
where
|
||||||
T: FromStr<Err = FlowyError>,
|
T: FromCellString,
|
||||||
{
|
{
|
||||||
fn from(s: String) -> Self {
|
fn from(s: String) -> Self {
|
||||||
match T::from_str(&s) {
|
match T::from_cell_str(&s) {
|
||||||
Ok(inner) => Parser(Some(inner)),
|
Ok(inner) => CellData(Some(inner)),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::error!("Deserialize Cell Data failed: {}", e);
|
tracing::error!("Deserialize Cell Data failed: {}", e);
|
||||||
Parser(None)
|
CellData(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::convert::From<String> for CellData<String> {
|
||||||
|
fn from(s: String) -> Self {
|
||||||
|
CellData(Some(s))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::convert::From<CellData<String>> for String {
|
||||||
|
fn from(p: CellData<String>) -> Self {
|
||||||
|
p.try_into_inner().unwrap_or("".to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The data is encoded by protobuf or utf8. You should choose the corresponding decode struct to parse it.
|
/// The data is encoded by protobuf or utf8. You should choose the corresponding decode struct to parse it.
|
||||||
///
|
///
|
||||||
/// For example:
|
/// For example:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user