refactor: type option impl trait

This commit is contained in:
nathan 2022-12-12 17:36:36 +08:00
parent e141e7ee63
commit 9ba17e004e
37 changed files with 268 additions and 226 deletions

View File

@ -1,10 +1,10 @@
use crate::entities::parser::NotEmptyStr;
use crate::entities::FieldType;
use crate::services::sort::SortType;
use bytes::Bytes;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::ErrorCode;
use grid_rev_model::{FieldRevision, FieldTypeRevision};
use grid_rev_model::FieldTypeRevision;
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
pub struct GridSortPB {

View File

@ -411,14 +411,14 @@ pub(crate) async fn get_select_option_handler(
//
let cell_rev = editor.get_cell_rev(&params.row_id, &params.field_id).await?;
let type_option = select_type_option_from_field_rev(&field_rev)?;
let any_cell_data: TypeCellData = match cell_rev {
let type_cell_data: TypeCellData = match cell_rev {
None => TypeCellData {
data: "".to_string(),
field_type: field_rev.ty.into(),
},
Some(cell_rev) => cell_rev.try_into()?,
};
let selected_options = type_option.get_selected_options(any_cell_data.into());
let selected_options = type_option.get_selected_options(type_cell_data.into());
data_result(selected_options)
}
}

View File

@ -7,19 +7,25 @@ use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use grid_rev_model::{CellRevision, FieldRevision, FieldTypeRevision};
/// This trait is used when doing filter/search on the grid.
pub trait CellFilterOperation<T> {
/// Return true if any_cell_data match the filter condition.
fn apply_filter(&self, any_cell_data: TypeCellData, filter: &T) -> FlowyResult<bool>;
pub trait CellFilterable<T> {
/// Return true if type_cell_data match the filter condition.
fn apply_filter(&self, type_cell_data: TypeCellData, filter: &T) -> FlowyResult<bool>;
}
pub trait CellGroupOperation {
fn apply_group(&self, any_cell_data: TypeCellData, group_content: &str) -> FlowyResult<bool>;
pub trait CellComparable {
fn apply_cmp(&self, type_cell_data: &TypeCellData, other_type_cell_data: &TypeCellData) -> FlowyResult<bool>;
}
/// Return object that describes the cell.
pub trait CellDisplayable<CD> {
/// Serialize the cell data in Protobuf/String format.
///
/// Each cell data is a opaque data, it needs to deserialized to a concrete data struct.
/// Essentially when the field type is SingleSelect/Multi-Select, the cell data contains a
/// list of option ids. So it need to be decoded including convert the option's id to
/// option's name
///
pub trait CellDataSerialize<CD> {
/// Serialize the cell data into `CellBytes` that will be posted to the `Dart` side. Using the
/// corresponding protobuf struct implement in `Dart` to deserialize the data.
/// corresponding protobuf struct implemented in `Dart` to deserialize the data.
///
/// Using `utf8` to encode the cell data if the cell data use `String` as its data container.
/// Using `protobuf` to encode the cell data if the cell data use `Protobuf struct` as its data container.
@ -43,9 +49,9 @@ pub trait CellDisplayable<CD> {
///
/// returns: Result<CellBytes, FlowyError>
///
fn displayed_cell_bytes(
fn serialize_cell_data_to_bytes(
&self,
cell_data: CellData<CD>,
cell_data: IntoCellData<CD>,
decoded_field_type: &FieldType,
field_rev: &FieldRevision,
) -> FlowyResult<CellBytes>;
@ -55,14 +61,14 @@ pub trait CellDisplayable<CD> {
/// The cell data is not readable which means it can't display the cell data directly to user.
/// For example,
/// 1. the cell data is timestamp if its field type is FieldType::Date that is not readable.
/// It needs to be parsed as the date string.
/// So it needs to be parsed as the date string with custom format setting.
///
/// 2. the cell data is a commas separated id if its field type if FieldType::MultiSelect that is not readable.
/// It needs to be parsed as a commas separated option name.
/// So it needs to be parsed as a commas separated option name.
///
fn displayed_cell_string(
fn serialize_cell_data_to_str(
&self,
cell_data: CellData<CD>,
cell_data: IntoCellData<CD>,
decoded_field_type: &FieldType,
field_rev: &FieldRevision,
) -> FlowyResult<String>;
@ -76,7 +82,10 @@ pub trait CellDataOperation<CD, CS> {
/// FieldType::URL => URLCellData
/// FieldType::Date=> DateCellData
///
/// Each cell data is a opaque data, it needs to deserialized to a concrete data struct
/// Each cell data is a opaque data, it needs to deserialized to a concrete data struct.
/// Essentially when the field type is SingleSelect/Multi-Select, the cell data contains a
/// list of option ids. So it need to be decoded including convert the option's id to
/// option's name
///
/// `cell_data`: the opaque data of the cell.
/// `decoded_field_type`: the field type of the cell data when doing serialization
@ -86,7 +95,7 @@ pub trait CellDataOperation<CD, CS> {
///
fn decode_cell_data(
&self,
cell_data: CellData<CD>,
cell_data: IntoCellData<CD>,
decoded_field_type: &FieldType,
field_rev: &FieldRevision,
) -> FlowyResult<CellBytes>;
@ -130,14 +139,14 @@ pub fn apply_cell_data_changeset<C: ToString, T: AsRef<FieldRevision>>(
Ok(TypeCellData::new(s, field_type).to_json())
}
pub fn decode_any_cell_data<T: TryInto<TypeCellData, Error = FlowyError> + Debug>(
pub fn decode_type_cell_data<T: TryInto<TypeCellData, Error = FlowyError> + Debug>(
data: T,
field_rev: &FieldRevision,
) -> (FieldType, CellBytes) {
let to_field_type = field_rev.ty.into();
match data.try_into() {
Ok(any_cell_data) => {
let TypeCellData { data, field_type } = any_cell_data;
Ok(type_cell_data) => {
let TypeCellData { data, field_type } = type_cell_data;
match try_decode_cell_data(data.into(), &field_type, &to_field_type, field_rev) {
Ok(cell_bytes) => (field_type, cell_bytes),
Err(e) => {
@ -156,40 +165,40 @@ pub fn decode_any_cell_data<T: TryInto<TypeCellData, Error = FlowyError> + Debug
}
}
pub fn decode_cell_data_to_string(
cell_data: CellData<String>,
pub fn decode_cell_data_to_string<C: Into<IntoCellData<String>>>(
cell_data: C,
from_field_type: &FieldType,
to_field_type: &FieldType,
field_rev: &FieldRevision,
) -> FlowyResult<String> {
let cell_data = cell_data.try_into_inner()?;
let cell_data = cell_data.into().try_into_inner()?;
let get_cell_display_str = || {
let field_type: FieldTypeRevision = to_field_type.into();
let result = match to_field_type {
FieldType::RichText => field_rev
.get_type_option::<RichTextTypeOptionPB>(field_type)?
.displayed_cell_string(cell_data.into(), from_field_type, field_rev),
.serialize_cell_data_to_str(cell_data.into(), from_field_type, field_rev),
FieldType::Number => field_rev
.get_type_option::<NumberTypeOptionPB>(field_type)?
.displayed_cell_string(cell_data.into(), from_field_type, field_rev),
.serialize_cell_data_to_str(cell_data.into(), from_field_type, field_rev),
FieldType::DateTime => field_rev
.get_type_option::<DateTypeOptionPB>(field_type)?
.displayed_cell_string(cell_data.into(), from_field_type, field_rev),
.serialize_cell_data_to_str(cell_data.into(), from_field_type, field_rev),
FieldType::SingleSelect => field_rev
.get_type_option::<SingleSelectTypeOptionPB>(field_type)?
.displayed_cell_string(cell_data.into(), from_field_type, field_rev),
.serialize_cell_data_to_str(cell_data.into(), from_field_type, field_rev),
FieldType::MultiSelect => field_rev
.get_type_option::<MultiSelectTypeOptionPB>(field_type)?
.displayed_cell_string(cell_data.into(), from_field_type, field_rev),
.serialize_cell_data_to_str(cell_data.into(), from_field_type, field_rev),
FieldType::Checklist => field_rev
.get_type_option::<ChecklistTypeOptionPB>(field_type)?
.displayed_cell_string(cell_data.into(), from_field_type, field_rev),
.serialize_cell_data_to_str(cell_data.into(), from_field_type, field_rev),
FieldType::Checkbox => field_rev
.get_type_option::<CheckboxTypeOptionPB>(field_type)?
.displayed_cell_string(cell_data.into(), from_field_type, field_rev),
.serialize_cell_data_to_str(cell_data.into(), from_field_type, field_rev),
FieldType::URL => field_rev
.get_type_option::<URLTypeOptionPB>(field_type)?
.displayed_cell_string(cell_data.into(), from_field_type, field_rev),
.serialize_cell_data_to_str(cell_data.into(), from_field_type, field_rev),
};
Some(result)
};
@ -210,7 +219,7 @@ pub fn decode_cell_data_to_string(
/// and `CellDataOperation` traits.
///
pub fn try_decode_cell_data(
cell_data: CellData<String>,
cell_data: IntoCellData<String>,
from_field_type: &FieldType,
to_field_type: &FieldType,
field_rev: &FieldRevision,
@ -312,9 +321,10 @@ pub trait FromCellString {
Self: Sized;
}
/// CellData is a helper struct. String will be parser into Option<T> only if the T impl the FromCellString trait.
pub struct CellData<T>(pub Option<T>);
impl<T> CellData<T> {
/// IntoCellData is a helper struct. String will be parser into Option<T> only if the T impl the FromCellString trait.
///
pub struct IntoCellData<T>(pub Option<T>);
impl<T> IntoCellData<T> {
pub fn try_into_inner(self) -> FlowyResult<T> {
match self.0 {
None => Err(ErrorCode::InvalidData.into()),
@ -323,35 +333,35 @@ impl<T> CellData<T> {
}
}
impl<T> std::convert::From<String> for CellData<T>
impl<T> std::convert::From<String> for IntoCellData<T>
where
T: FromCellString,
{
fn from(s: String) -> Self {
match T::from_cell_str(&s) {
Ok(inner) => CellData(Some(inner)),
Ok(inner) => IntoCellData(Some(inner)),
Err(e) => {
tracing::error!("Deserialize Cell Data failed: {}", e);
CellData(None)
IntoCellData(None)
}
}
}
}
impl std::convert::From<usize> for CellData<String> {
impl std::convert::From<usize> for IntoCellData<String> {
fn from(n: usize) -> Self {
CellData(Some(n.to_string()))
IntoCellData(Some(n.to_string()))
}
}
impl<T> std::convert::From<T> for CellData<T> {
impl<T> std::convert::From<T> for IntoCellData<T> {
fn from(val: T) -> Self {
CellData(Some(val))
IntoCellData(Some(val))
}
}
impl std::convert::From<CellData<String>> for String {
fn from(p: CellData<String>) -> Self {
impl std::convert::From<IntoCellData<String>> for String {
fn from(p: IntoCellData<String>) -> Self {
p.try_into_inner().unwrap_or_else(|_| String::new())
}
}

View File

@ -1,5 +1,5 @@
mod any_cell_data;
mod cell_operation;
mod type_cell_data;
pub use any_cell_data::*;
pub use cell_operation::*;
pub use type_cell_data::*;

View File

@ -1,13 +1,13 @@
use crate::entities::FieldType;
use crate::services::cell::{CellData, FromCellString};
use crate::services::cell::{FromCellString, IntoCellData};
use bytes::Bytes;
use flowy_error::{internal_error, FlowyError, FlowyResult};
use grid_rev_model::CellRevision;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
/// TypeCellData is a generic CellData, you can parse the cell_data according to the field_type.
/// When the type of field is changed, it's different from the field_type of AnyCellData.
/// TypeCellData is a generic CellData, you can parse the type_cell_data according to the field_type.
/// When the type of field is changed, it's different from the field_type of TypeCellData.
/// So it will return an empty data. You could check the CellDataOperation trait for more information.
#[derive(Debug, Serialize, Deserialize)]
pub struct TypeCellData {
@ -60,12 +60,12 @@ impl std::convert::TryFrom<CellRevision> for TypeCellData {
}
}
impl<T> std::convert::From<TypeCellData> for CellData<T>
impl<T> std::convert::From<TypeCellData> for IntoCellData<T>
where
T: FromCellString,
{
fn from(any_call_data: TypeCellData) -> Self {
CellData::from(any_call_data.data)
IntoCellData::from(any_call_data.data)
}
}

View File

@ -1,5 +1,5 @@
use crate::entities::{CheckboxFilterConditionPB, CheckboxFilterPB};
use crate::services::cell::{CellData, CellFilterOperation, TypeCellData};
use crate::services::cell::{CellFilterable, IntoCellData, TypeCellData};
use crate::services::field::{CheckboxCellData, CheckboxTypeOptionPB};
use flowy_error::FlowyResult;
@ -13,12 +13,12 @@ impl CheckboxFilterPB {
}
}
impl CellFilterOperation<CheckboxFilterPB> for CheckboxTypeOptionPB {
fn apply_filter(&self, any_cell_data: TypeCellData, filter: &CheckboxFilterPB) -> FlowyResult<bool> {
if !any_cell_data.is_checkbox() {
impl CellFilterable<CheckboxFilterPB> for CheckboxTypeOptionPB {
fn apply_filter(&self, type_cell_data: TypeCellData, filter: &CheckboxFilterPB) -> FlowyResult<bool> {
if !type_cell_data.is_checkbox() {
return Ok(true);
}
let cell_data: CellData<CheckboxCellData> = any_cell_data.into();
let cell_data: IntoCellData<CheckboxCellData> = type_cell_data.into();
let checkbox_cell_data = cell_data.try_into_inner()?;
Ok(filter.is_visible(&checkbox_cell_data))
}

View File

@ -1,6 +1,6 @@
use crate::entities::FieldType;
use crate::impl_type_option;
use crate::services::cell::{AnyCellChangeset, CellBytes, CellData, CellDataOperation, CellDisplayable};
use crate::services::cell::{AnyCellChangeset, CellBytes, CellDataOperation, CellDataSerialize, IntoCellData};
use crate::services::field::{BoxTypeOptionBuilder, CheckboxCellData, TypeOptionBuilder};
use bytes::Bytes;
use flowy_derive::ProtoBuf;
@ -42,10 +42,10 @@ pub struct CheckboxTypeOptionPB {
}
impl_type_option!(CheckboxTypeOptionPB, FieldType::Checkbox);
impl CellDisplayable<CheckboxCellData> for CheckboxTypeOptionPB {
fn displayed_cell_bytes(
impl CellDataSerialize<CheckboxCellData> for CheckboxTypeOptionPB {
fn serialize_cell_data_to_bytes(
&self,
cell_data: CellData<CheckboxCellData>,
cell_data: IntoCellData<CheckboxCellData>,
_decoded_field_type: &FieldType,
_field_rev: &FieldRevision,
) -> FlowyResult<CellBytes> {
@ -53,9 +53,9 @@ impl CellDisplayable<CheckboxCellData> for CheckboxTypeOptionPB {
Ok(CellBytes::new(cell_data))
}
fn displayed_cell_string(
fn serialize_cell_data_to_str(
&self,
cell_data: CellData<CheckboxCellData>,
cell_data: IntoCellData<CheckboxCellData>,
_decoded_field_type: &FieldType,
_field_rev: &FieldRevision,
) -> FlowyResult<String> {
@ -69,7 +69,7 @@ pub type CheckboxCellChangeset = String;
impl CellDataOperation<CheckboxCellData, CheckboxCellChangeset> for CheckboxTypeOptionPB {
fn decode_cell_data(
&self,
cell_data: CellData<CheckboxCellData>,
cell_data: IntoCellData<CheckboxCellData>,
decoded_field_type: &FieldType,
field_rev: &FieldRevision,
) -> FlowyResult<CellBytes> {
@ -77,7 +77,7 @@ impl CellDataOperation<CheckboxCellData, CheckboxCellChangeset> for CheckboxType
return Ok(CellBytes::default());
}
self.displayed_cell_bytes(cell_data, decoded_field_type, field_rev)
self.serialize_cell_data_to_bytes(cell_data, decoded_field_type, field_rev)
}
fn apply_changeset(

View File

@ -73,7 +73,7 @@ impl CellBytesParser for CheckboxCellDataParser {
type Object = CheckboxCellData;
fn parser(bytes: &Bytes) -> FlowyResult<Self::Object> {
match String::from_utf8(bytes.to_vec()) {
Ok(s) => CheckboxCellData::from_str(&s),
Ok(s) => CheckboxCellData::from_cell_str(&s),
Err(_) => Ok(CheckboxCellData("".to_string())),
}
}

View File

@ -1,5 +1,5 @@
use crate::entities::{DateFilterConditionPB, DateFilterPB};
use crate::services::cell::{CellData, CellFilterOperation, TypeCellData};
use crate::services::cell::{CellFilterable, IntoCellData, TypeCellData};
use crate::services::field::{DateTimestamp, DateTypeOptionPB};
use chrono::NaiveDateTime;
use flowy_error::FlowyResult;
@ -59,12 +59,12 @@ impl DateFilterPB {
}
}
impl CellFilterOperation<DateFilterPB> for DateTypeOptionPB {
fn apply_filter(&self, any_cell_data: TypeCellData, filter: &DateFilterPB) -> FlowyResult<bool> {
if !any_cell_data.is_date() {
impl CellFilterable<DateFilterPB> for DateTypeOptionPB {
fn apply_filter(&self, type_cell_data: TypeCellData, filter: &DateFilterPB) -> FlowyResult<bool> {
if !type_cell_data.is_date() {
return Ok(true);
}
let cell_data: CellData<DateTimestamp> = any_cell_data.into();
let cell_data: IntoCellData<DateTimestamp> = type_cell_data.into();
let timestamp = cell_data.try_into_inner()?;
Ok(filter.is_visible(timestamp))
}

View File

@ -1,6 +1,6 @@
use crate::entities::FieldType;
use crate::impl_type_option;
use crate::services::cell::{AnyCellChangeset, CellBytes, CellData, CellDataOperation, CellDisplayable};
use crate::services::cell::{AnyCellChangeset, CellBytes, CellDataOperation, CellDataSerialize, IntoCellData};
use crate::services::field::{
BoxTypeOptionBuilder, DateCellChangeset, DateCellDataPB, DateFormat, DateTimestamp, TimeFormat, TypeOptionBuilder,
};
@ -107,21 +107,21 @@ impl DateTypeOptionPB {
}
}
impl CellDisplayable<DateTimestamp> for DateTypeOptionPB {
fn displayed_cell_bytes(
impl CellDataSerialize<DateTimestamp> for DateTypeOptionPB {
fn serialize_cell_data_to_bytes(
&self,
cell_data: CellData<DateTimestamp>,
cell_data: IntoCellData<DateTimestamp>,
_decoded_field_type: &FieldType,
_field_rev: &FieldRevision,
) -> FlowyResult<CellBytes> {
let timestamp = cell_data.try_into_inner()?;
let date_cell_data = self.today_desc_from_timestamp(timestamp);
CellBytes::from(date_cell_data)
let cell_data_pb = self.today_desc_from_timestamp(timestamp);
CellBytes::from(cell_data_pb)
}
fn displayed_cell_string(
fn serialize_cell_data_to_str(
&self,
cell_data: CellData<DateTimestamp>,
cell_data: IntoCellData<DateTimestamp>,
_decoded_field_type: &FieldType,
_field_rev: &FieldRevision,
) -> FlowyResult<String> {
@ -134,7 +134,7 @@ impl CellDisplayable<DateTimestamp> for DateTypeOptionPB {
impl CellDataOperation<DateTimestamp, DateCellChangeset> for DateTypeOptionPB {
fn decode_cell_data(
&self,
cell_data: CellData<DateTimestamp>,
cell_data: IntoCellData<DateTimestamp>,
decoded_field_type: &FieldType,
field_rev: &FieldRevision,
) -> FlowyResult<CellBytes> {
@ -145,7 +145,7 @@ impl CellDataOperation<DateTimestamp, DateCellChangeset> for DateTypeOptionPB {
if !decoded_field_type.is_date() {
return Ok(CellBytes::default());
}
self.displayed_cell_bytes(cell_data, decoded_field_type, field_rev)
self.serialize_cell_data_to_bytes(cell_data, decoded_field_type, field_rev)
}
fn apply_changeset(

View File

@ -1,5 +1,5 @@
use crate::entities::{NumberFilterConditionPB, NumberFilterPB};
use crate::services::cell::{CellFilterOperation, TypeCellData};
use crate::services::cell::{CellFilterable, TypeCellData};
use crate::services::field::{NumberCellData, NumberTypeOptionPB};
use flowy_error::FlowyResult;
use rust_decimal::prelude::Zero;
@ -37,13 +37,13 @@ impl NumberFilterPB {
}
}
impl CellFilterOperation<NumberFilterPB> for NumberTypeOptionPB {
fn apply_filter(&self, any_cell_data: TypeCellData, filter: &NumberFilterPB) -> FlowyResult<bool> {
if !any_cell_data.is_number() {
impl CellFilterable<NumberFilterPB> for NumberTypeOptionPB {
fn apply_filter(&self, type_cell_data: TypeCellData, filter: &NumberFilterPB) -> FlowyResult<bool> {
if !type_cell_data.is_number() {
return Ok(true);
}
let cell_data = any_cell_data.data;
let cell_data = type_cell_data.data;
let num_cell_data = self.format_cell_data(&cell_data)?;
Ok(filter.is_visible(&num_cell_data))

View File

@ -1,15 +1,13 @@
use crate::entities::FieldType;
use crate::impl_type_option;
use crate::services::cell::{AnyCellChangeset, CellBytes, CellData, CellDataOperation, CellDisplayable};
use crate::services::cell::{AnyCellChangeset, CellBytes, CellDataOperation, CellDataSerialize, IntoCellData};
use crate::services::field::type_options::number_type_option::format::*;
use crate::services::field::{BoxTypeOptionBuilder, NumberCellData, TypeOptionBuilder};
use bytes::Bytes;
use flowy_derive::ProtoBuf;
use flowy_error::{FlowyError, FlowyResult};
use grid_rev_model::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataSerializer};
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
@ -105,10 +103,10 @@ pub(crate) fn strip_currency_symbol<T: ToString>(s: T) -> String {
s
}
impl CellDisplayable<String> for NumberTypeOptionPB {
fn displayed_cell_bytes(
impl CellDataSerialize<String> for NumberTypeOptionPB {
fn serialize_cell_data_to_bytes(
&self,
cell_data: CellData<String>,
cell_data: IntoCellData<String>,
_decoded_field_type: &FieldType,
_field_rev: &FieldRevision,
) -> FlowyResult<CellBytes> {
@ -119,9 +117,9 @@ impl CellDisplayable<String> for NumberTypeOptionPB {
}
}
fn displayed_cell_string(
fn serialize_cell_data_to_str(
&self,
cell_data: CellData<String>,
cell_data: IntoCellData<String>,
_decoded_field_type: &FieldType,
_field_rev: &FieldRevision,
) -> FlowyResult<String> {
@ -135,7 +133,7 @@ pub type NumberCellChangeset = String;
impl CellDataOperation<String, NumberCellChangeset> for NumberTypeOptionPB {
fn decode_cell_data(
&self,
cell_data: CellData<String>,
cell_data: IntoCellData<String>,
decoded_field_type: &FieldType,
field_rev: &FieldRevision,
) -> FlowyResult<CellBytes> {
@ -143,7 +141,7 @@ impl CellDataOperation<String, NumberCellChangeset> for NumberTypeOptionPB {
return Ok(CellBytes::default());
}
self.displayed_cell_bytes(cell_data, decoded_field_type, field_rev)
self.serialize_cell_data_to_bytes(cell_data, decoded_field_type, field_rev)
}
fn apply_changeset(

View File

@ -99,6 +99,7 @@ impl CellDataIsEmpty for NumberCellData {
self.decimal.is_none()
}
}
pub struct NumberCellDataParser();
impl CellBytesParser for NumberCellDataParser {
type Object = NumberCellData;

View File

@ -1,6 +1,6 @@
use crate::entities::FieldType;
use crate::impl_type_option;
use crate::services::cell::{AnyCellChangeset, CellBytes, CellData, CellDataOperation, CellDisplayable};
use crate::services::cell::{AnyCellChangeset, CellBytes, CellDataOperation, CellDataSerialize, IntoCellData};
use crate::services::field::selection_type_option::type_option_transform::SelectOptionTypeOptionTransformer;
use crate::services::field::type_options::util::get_cell_data;
use crate::services::field::{
@ -41,11 +41,11 @@ impl SelectTypeOptionSharedAction for ChecklistTypeOptionPB {
impl CellDataOperation<SelectOptionIds, SelectOptionCellChangeset> for ChecklistTypeOptionPB {
fn decode_cell_data(
&self,
cell_data: CellData<SelectOptionIds>,
cell_data: IntoCellData<SelectOptionIds>,
decoded_field_type: &FieldType,
field_rev: &FieldRevision,
) -> FlowyResult<CellBytes> {
self.displayed_cell_bytes(cell_data, decoded_field_type, field_rev)
self.serialize_cell_data_to_bytes(cell_data, decoded_field_type, field_rev)
}
fn apply_changeset(

View File

@ -1,6 +1,6 @@
use crate::entities::FieldType;
use crate::impl_type_option;
use crate::services::cell::{AnyCellChangeset, CellBytes, CellData, CellDataOperation, CellDisplayable};
use crate::services::cell::{AnyCellChangeset, CellBytes, CellDataOperation, CellDataSerialize, IntoCellData};
use crate::services::field::selection_type_option::type_option_transform::SelectOptionTypeOptionTransformer;
use crate::services::field::type_options::util::get_cell_data;
use crate::services::field::{
@ -41,11 +41,11 @@ impl SelectTypeOptionSharedAction for MultiSelectTypeOptionPB {
impl CellDataOperation<SelectOptionIds, SelectOptionCellChangeset> for MultiSelectTypeOptionPB {
fn decode_cell_data(
&self,
cell_data: CellData<SelectOptionIds>,
cell_data: IntoCellData<SelectOptionIds>,
decoded_field_type: &FieldType,
field_rev: &FieldRevision,
) -> FlowyResult<CellBytes> {
self.displayed_cell_bytes(cell_data, decoded_field_type, field_rev)
self.serialize_cell_data_to_bytes(cell_data, decoded_field_type, field_rev)
}
fn apply_changeset(

View File

@ -1,7 +1,7 @@
#![allow(clippy::needless_collect)]
use crate::entities::{ChecklistFilterPB, FieldType, SelectOptionConditionPB, SelectOptionFilterPB};
use crate::services::cell::{CellFilterOperation, TypeCellData};
use crate::services::cell::{CellFilterable, TypeCellData};
use crate::services::field::{ChecklistTypeOptionPB, MultiSelectTypeOptionPB, SingleSelectTypeOptionPB};
use crate::services::field::{SelectTypeOptionSharedAction, SelectedSelectOptions};
use flowy_error::FlowyResult;
@ -78,33 +78,33 @@ impl SelectOptionFilterPB {
}
}
impl CellFilterOperation<SelectOptionFilterPB> for MultiSelectTypeOptionPB {
fn apply_filter(&self, any_cell_data: TypeCellData, filter: &SelectOptionFilterPB) -> FlowyResult<bool> {
if !any_cell_data.is_multi_select() {
impl CellFilterable<SelectOptionFilterPB> for MultiSelectTypeOptionPB {
fn apply_filter(&self, type_cell_data: TypeCellData, filter: &SelectOptionFilterPB) -> FlowyResult<bool> {
if !type_cell_data.is_multi_select() {
return Ok(true);
}
let selected_options = SelectedSelectOptions::from(self.get_selected_options(any_cell_data.into()));
let selected_options = SelectedSelectOptions::from(self.get_selected_options(type_cell_data.into()));
Ok(filter.is_visible(&selected_options, FieldType::MultiSelect))
}
}
impl CellFilterOperation<SelectOptionFilterPB> for SingleSelectTypeOptionPB {
fn apply_filter(&self, any_cell_data: TypeCellData, filter: &SelectOptionFilterPB) -> FlowyResult<bool> {
if !any_cell_data.is_single_select() {
impl CellFilterable<SelectOptionFilterPB> for SingleSelectTypeOptionPB {
fn apply_filter(&self, type_cell_data: TypeCellData, filter: &SelectOptionFilterPB) -> FlowyResult<bool> {
if !type_cell_data.is_single_select() {
return Ok(true);
}
let selected_options = SelectedSelectOptions::from(self.get_selected_options(any_cell_data.into()));
let selected_options = SelectedSelectOptions::from(self.get_selected_options(type_cell_data.into()));
Ok(filter.is_visible(&selected_options, FieldType::SingleSelect))
}
}
impl CellFilterOperation<ChecklistFilterPB> for ChecklistTypeOptionPB {
fn apply_filter(&self, any_cell_data: TypeCellData, filter: &ChecklistFilterPB) -> FlowyResult<bool> {
if !any_cell_data.is_checklist() {
impl CellFilterable<ChecklistFilterPB> for ChecklistTypeOptionPB {
fn apply_filter(&self, type_cell_data: TypeCellData, filter: &ChecklistFilterPB) -> FlowyResult<bool> {
if !type_cell_data.is_checklist() {
return Ok(true);
}
let selected_options = SelectedSelectOptions::from(self.get_selected_options(any_cell_data.into()));
let selected_options = SelectedSelectOptions::from(self.get_selected_options(type_cell_data.into()));
Ok(filter.is_visible(&self.options, &selected_options))
}
}

View File

@ -1,7 +1,7 @@
use crate::entities::parser::NotEmptyStr;
use crate::entities::{CellChangesetPB, CellPathPB, CellPathParams, FieldType};
use crate::services::cell::{
CellBytes, CellBytesParser, CellData, CellDataIsEmpty, CellDisplayable, FromCellChangeset, FromCellString,
CellBytes, CellBytesParser, CellDataIsEmpty, CellDataSerialize, FromCellChangeset, FromCellString, IntoCellData,
};
use crate::services::field::selection_type_option::type_option_transform::SelectOptionTypeOptionTransformer;
use crate::services::field::{ChecklistTypeOptionPB, MultiSelectTypeOptionPB, SingleSelectTypeOptionPB};
@ -69,7 +69,10 @@ impl std::default::Default for SelectOptionColorPB {
}
}
pub fn make_selected_options(cell_data: CellData<SelectOptionIds>, options: &[SelectOptionPB]) -> Vec<SelectOptionPB> {
pub fn make_selected_options(
cell_data: IntoCellData<SelectOptionIds>,
options: &[SelectOptionPB],
) -> Vec<SelectOptionPB> {
if let Ok(ids) = cell_data.try_into_inner() {
ids.iter()
.flat_map(|option_id| options.iter().find(|option| &option.id == option_id).cloned())
@ -110,7 +113,7 @@ pub trait SelectTypeOptionSharedAction: TypeOptionDataSerializer + Send + Sync {
}
/// Return a list of options that are selected by user
fn get_selected_options(&self, cell_data: CellData<SelectOptionIds>) -> SelectOptionCellDataPB {
fn get_selected_options(&self, cell_data: IntoCellData<SelectOptionIds>) -> SelectOptionCellDataPB {
let mut select_options = make_selected_options(cell_data, self.options());
match self.number_of_max_options() {
None => {}
@ -126,7 +129,7 @@ pub trait SelectTypeOptionSharedAction: TypeOptionDataSerializer + Send + Sync {
fn transform_cell_data(
&self,
cell_data: CellData<SelectOptionIds>,
cell_data: IntoCellData<SelectOptionIds>,
decoded_field_type: &FieldType,
_field_rev: &FieldRevision,
) -> FlowyResult<CellBytes> {
@ -150,7 +153,9 @@ pub trait SelectTypeOptionSharedAction: TypeOptionDataSerializer + Send + Sync {
})
});
return CellBytes::from(self.get_selected_options(CellData(Some(SelectOptionIds(transformed_ids)))));
return CellBytes::from(
self.get_selected_options(IntoCellData(Some(SelectOptionIds(transformed_ids)))),
);
}
_ => {
return Ok(CellBytes::default());
@ -165,13 +170,13 @@ pub trait SelectTypeOptionSharedAction: TypeOptionDataSerializer + Send + Sync {
fn mut_options(&mut self) -> &mut Vec<SelectOptionPB>;
}
impl<T> CellDisplayable<SelectOptionIds> for T
impl<T> CellDataSerialize<SelectOptionIds> for T
where
T: SelectTypeOptionSharedAction,
{
fn displayed_cell_bytes(
fn serialize_cell_data_to_bytes(
&self,
cell_data: CellData<SelectOptionIds>,
cell_data: IntoCellData<SelectOptionIds>,
decoded_field_type: &FieldType,
field_rev: &FieldRevision,
) -> FlowyResult<CellBytes> {
@ -183,9 +188,9 @@ where
)
}
fn displayed_cell_string(
fn serialize_cell_data_to_str(
&self,
cell_data: CellData<SelectOptionIds>,
cell_data: IntoCellData<SelectOptionIds>,
_decoded_field_type: &FieldType,
_field_rev: &FieldRevision,
) -> FlowyResult<String> {

View File

@ -1,6 +1,6 @@
use crate::entities::FieldType;
use crate::impl_type_option;
use crate::services::cell::{AnyCellChangeset, CellBytes, CellData, CellDataOperation, CellDisplayable};
use crate::services::cell::{AnyCellChangeset, CellBytes, CellDataOperation, CellDataSerialize, IntoCellData};
use crate::services::field::selection_type_option::type_option_transform::SelectOptionTypeOptionTransformer;
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
use crate::services::field::{
@ -40,11 +40,11 @@ impl SelectTypeOptionSharedAction for SingleSelectTypeOptionPB {
impl CellDataOperation<SelectOptionIds, SelectOptionCellChangeset> for SingleSelectTypeOptionPB {
fn decode_cell_data(
&self,
cell_data: CellData<SelectOptionIds>,
cell_data: IntoCellData<SelectOptionIds>,
decoded_field_type: &FieldType,
field_rev: &FieldRevision,
) -> FlowyResult<CellBytes> {
self.displayed_cell_bytes(cell_data, decoded_field_type, field_rev)
self.serialize_cell_data_to_bytes(cell_data, decoded_field_type, field_rev)
}
fn apply_changeset(

View File

@ -1,5 +1,5 @@
use crate::entities::FieldType;
use crate::services::cell::{CellBytes, CellData};
use crate::services::cell::{CellBytes, IntoCellData};
use crate::services::field::{
MultiSelectTypeOptionPB, SelectOptionColorPB, SelectOptionIds, SelectOptionPB, SelectTypeOptionSharedAction,
SingleSelectTypeOptionPB, CHECK, UNCHECK,
@ -57,7 +57,7 @@ impl SelectOptionTypeOptionTransformer {
pub fn transform_type_option_cell_data<T>(
shared: &T,
cell_data: CellData<SelectOptionIds>,
cell_data: IntoCellData<SelectOptionIds>,
decoded_field_type: &FieldType,
_field_rev: &FieldRevision,
) -> FlowyResult<CellBytes>
@ -78,7 +78,7 @@ impl SelectOptionTypeOptionTransformer {
transformed_ids.push(option.id.clone());
}
});
let transformed_cell_data = CellData::from(SelectOptionIds::from(transformed_ids));
let transformed_cell_data = IntoCellData::from(SelectOptionIds::from(transformed_ids));
CellBytes::from(shared.get_selected_options(transformed_cell_data))
}
_ => Ok(CellBytes::default()),

View File

@ -1,5 +1,5 @@
use crate::entities::{TextFilterConditionPB, TextFilterPB};
use crate::services::cell::{CellData, CellFilterOperation, TypeCellData};
use crate::services::cell::{CellFilterable, IntoCellData, TypeCellData};
use crate::services::field::{RichTextTypeOptionPB, TextCellData};
use flowy_error::FlowyResult;
@ -20,13 +20,13 @@ impl TextFilterPB {
}
}
impl CellFilterOperation<TextFilterPB> for RichTextTypeOptionPB {
fn apply_filter(&self, any_cell_data: TypeCellData, filter: &TextFilterPB) -> FlowyResult<bool> {
if !any_cell_data.is_text() {
impl CellFilterable<TextFilterPB> for RichTextTypeOptionPB {
fn apply_filter(&self, type_cell_data: TypeCellData, filter: &TextFilterPB) -> FlowyResult<bool> {
if !type_cell_data.is_text() {
return Ok(false);
}
let cell_data: CellData<TextCellData> = any_cell_data.into();
let cell_data: IntoCellData<TextCellData> = type_cell_data.into();
let text_cell_data = cell_data.try_into_inner()?;
Ok(filter.is_visible(text_cell_data))
}

View File

@ -1,8 +1,8 @@
use crate::entities::FieldType;
use crate::impl_type_option;
use crate::services::cell::{
decode_cell_data_to_string, AnyCellChangeset, CellBytes, CellBytesParser, CellData, CellDataIsEmpty,
CellDataOperation, CellDisplayable, FromCellString,
decode_cell_data_to_string, AnyCellChangeset, CellBytes, CellBytesParser, CellDataIsEmpty, CellDataOperation,
CellDataSerialize, FromCellString, IntoCellData,
};
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
use bytes::Bytes;
@ -39,32 +39,32 @@ pub struct RichTextTypeOptionPB {
}
impl_type_option!(RichTextTypeOptionPB, FieldType::RichText);
impl CellDisplayable<String> for RichTextTypeOptionPB {
fn displayed_cell_bytes(
impl CellDataSerialize<RichTextCellData> for RichTextTypeOptionPB {
fn serialize_cell_data_to_bytes(
&self,
cell_data: CellData<String>,
cell_data: IntoCellData<RichTextCellData>,
_decoded_field_type: &FieldType,
_field_rev: &FieldRevision,
) -> FlowyResult<CellBytes> {
let cell_str: String = cell_data.try_into_inner()?;
let cell_str: RichTextCellData = cell_data.try_into_inner()?;
Ok(CellBytes::new(cell_str))
}
fn displayed_cell_string(
fn serialize_cell_data_to_str(
&self,
cell_data: CellData<String>,
cell_data: IntoCellData<RichTextCellData>,
_decoded_field_type: &FieldType,
_field_rev: &FieldRevision,
) -> FlowyResult<String> {
let cell_str: String = cell_data.try_into_inner()?;
let cell_str: RichTextCellData = cell_data.try_into_inner()?;
Ok(cell_str)
}
}
impl CellDataOperation<String, String> for RichTextTypeOptionPB {
impl CellDataOperation<RichTextCellData, String> for RichTextTypeOptionPB {
fn decode_cell_data(
&self,
cell_data: CellData<String>,
cell_data: IntoCellData<RichTextCellData>,
decoded_field_type: &FieldType,
field_rev: &FieldRevision,
) -> FlowyResult<CellBytes> {
@ -77,7 +77,7 @@ impl CellDataOperation<String, String> for RichTextTypeOptionPB {
let s = decode_cell_data_to_string(cell_data, decoded_field_type, decoded_field_type, field_rev);
Ok(CellBytes::new(s.unwrap_or_else(|_| "".to_owned())))
} else {
self.displayed_cell_bytes(cell_data, decoded_field_type, field_rev)
self.serialize_cell_data_to_bytes(cell_data, decoded_field_type, field_rev)
}
}
@ -141,3 +141,5 @@ impl CellBytesParser for TextCellDataParser {
}
}
}
pub type RichTextCellData = String;

View File

@ -1,15 +1,15 @@
use crate::entities::TextFilterPB;
use crate::services::cell::{CellData, CellFilterOperation, TypeCellData};
use crate::services::cell::{CellFilterable, IntoCellData, TypeCellData};
use crate::services::field::{TextCellData, URLTypeOptionPB};
use flowy_error::FlowyResult;
impl CellFilterOperation<TextFilterPB> for URLTypeOptionPB {
fn apply_filter(&self, any_cell_data: TypeCellData, filter: &TextFilterPB) -> FlowyResult<bool> {
if !any_cell_data.is_url() {
impl CellFilterable<TextFilterPB> for URLTypeOptionPB {
fn apply_filter(&self, type_cell_data: TypeCellData, filter: &TextFilterPB) -> FlowyResult<bool> {
if !type_cell_data.is_url() {
return Ok(true);
}
let cell_data: CellData<TextCellData> = any_cell_data.into();
let cell_data: IntoCellData<TextCellData> = type_cell_data.into();
let text_cell_data = cell_data.try_into_inner()?;
Ok(filter.is_visible(&text_cell_data))
}

View File

@ -1,9 +1,9 @@
#[cfg(test)]
mod tests {
use crate::entities::FieldType;
use crate::services::cell::{CellData, CellDataOperation};
use crate::services::cell::{CellDataOperation, IntoCellData};
use crate::services::field::{FieldBuilder, URLCellDataParser};
use crate::services::field::{URLCellDataPB, URLTypeOptionPB};
use crate::services::field::{URLCellData, URLTypeOptionPB};
use grid_rev_model::FieldRevision;
/// The expected_str will equal to the input string, but the expected_url will be empty if there's no
@ -175,12 +175,12 @@ mod tests {
assert_eq!(expected_url.to_owned(), decode_cell_data.url);
}
fn decode_cell_data<T: Into<CellData<URLCellDataPB>>>(
fn decode_cell_data<T: Into<IntoCellData<URLCellData>>>(
encoded_data: T,
type_option: &URLTypeOptionPB,
field_rev: &FieldRevision,
field_type: &FieldType,
) -> URLCellDataPB {
) -> URLCellData {
type_option
.decode_cell_data(encoded_data.into(), field_type, field_rev)
.unwrap()

View File

@ -1,7 +1,7 @@
use crate::entities::FieldType;
use crate::impl_type_option;
use crate::services::cell::{AnyCellChangeset, CellBytes, CellData, CellDataOperation, CellDisplayable};
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder, URLCellDataPB};
use crate::services::cell::{AnyCellChangeset, CellBytes, CellDataOperation, CellDataSerialize, IntoCellData};
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder, URLCellData, URLCellDataPB};
use bytes::Bytes;
use fancy_regex::Regex;
use flowy_derive::ProtoBuf;
@ -36,41 +36,42 @@ pub struct URLTypeOptionPB {
}
impl_type_option!(URLTypeOptionPB, FieldType::URL);
impl CellDisplayable<URLCellDataPB> for URLTypeOptionPB {
fn displayed_cell_bytes(
impl CellDataSerialize<URLCellData> for URLTypeOptionPB {
fn serialize_cell_data_to_bytes(
&self,
cell_data: CellData<URLCellDataPB>,
cell_data: IntoCellData<URLCellData>,
_decoded_field_type: &FieldType,
_field_rev: &FieldRevision,
) -> FlowyResult<CellBytes> {
let cell_data: URLCellDataPB = cell_data.try_into_inner()?;
CellBytes::from(cell_data)
let cell_data_pb: URLCellDataPB = cell_data.try_into_inner()?.into();
CellBytes::from(cell_data_pb)
}
fn displayed_cell_string(
fn serialize_cell_data_to_str(
&self,
cell_data: CellData<URLCellDataPB>,
cell_data: IntoCellData<URLCellData>,
_decoded_field_type: &FieldType,
_field_rev: &FieldRevision,
) -> FlowyResult<String> {
let cell_data: URLCellDataPB = cell_data.try_into_inner()?;
let cell_data: URLCellData = cell_data.try_into_inner()?;
Ok(cell_data.content)
}
}
pub type URLCellChangeset = String;
impl CellDataOperation<URLCellDataPB, URLCellChangeset> for URLTypeOptionPB {
impl CellDataOperation<URLCellData, URLCellChangeset> for URLTypeOptionPB {
fn decode_cell_data(
&self,
cell_data: CellData<URLCellDataPB>,
cell_data: IntoCellData<URLCellData>,
decoded_field_type: &FieldType,
field_rev: &FieldRevision,
_field_rev: &FieldRevision,
) -> FlowyResult<CellBytes> {
if !decoded_field_type.is_url() {
return Ok(CellBytes::default());
}
self.displayed_cell_bytes(cell_data, decoded_field_type, field_rev)
let cell_data = cell_data.try_into_inner()?.to_json()?;
Ok(CellBytes::new(cell_data))
}
fn apply_changeset(
@ -83,7 +84,7 @@ impl CellDataOperation<URLCellDataPB, URLCellChangeset> for URLTypeOptionPB {
if let Ok(Some(m)) = URL_REGEX.find(&content) {
url = auto_append_scheme(m.as_str());
}
URLCellDataPB { url, content }.to_json()
URLCellData { url, content }.to_json()
}
}

View File

@ -4,7 +4,7 @@ use flowy_derive::ProtoBuf;
use flowy_error::{internal_error, FlowyResult};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)]
#[derive(Clone, Debug, Default, ProtoBuf)]
pub struct URLCellDataPB {
#[pb(index = 1)]
pub url: String,
@ -13,7 +13,22 @@ pub struct URLCellDataPB {
pub content: String,
}
impl URLCellDataPB {
impl From<URLCellData> for URLCellDataPB {
fn from(data: URLCellData) -> Self {
Self {
url: data.url,
content: data.content,
}
}
}
#[derive(Clone, Default, Serialize, Deserialize)]
pub struct URLCellData {
pub url: String,
pub content: String,
}
impl URLCellData {
pub fn new(s: &str) -> Self {
Self {
url: "".to_string(),
@ -26,7 +41,7 @@ impl URLCellDataPB {
}
}
impl CellDataIsEmpty for URLCellDataPB {
impl CellDataIsEmpty for URLCellData {
fn is_empty(&self) -> bool {
self.content.is_empty()
}
@ -34,15 +49,18 @@ impl CellDataIsEmpty for URLCellDataPB {
pub struct URLCellDataParser();
impl CellBytesParser for URLCellDataParser {
type Object = URLCellDataPB;
type Object = URLCellData;
fn parser(bytes: &Bytes) -> FlowyResult<Self::Object> {
URLCellDataPB::try_from(bytes.as_ref()).map_err(internal_error)
match String::from_utf8(bytes.to_vec()) {
Ok(s) => URLCellData::from_cell_str(&s),
Err(_) => Ok(URLCellData::default()),
}
}
}
impl FromCellString for URLCellDataPB {
impl FromCellString for URLCellData {
fn from_cell_str(s: &str) -> FlowyResult<Self> {
serde_json::from_str::<URLCellDataPB>(s).map_err(internal_error)
serde_json::from_str::<URLCellData>(s).map_err(internal_error)
}
}

View File

@ -1,6 +1,6 @@
use crate::entities::filter_entities::*;
use crate::entities::{FieldType, InsertedRowPB, RowPB};
use crate::services::cell::{CellFilterOperation, TypeCellData};
use crate::services::cell::{CellFilterable, TypeCellData};
use crate::services::field::*;
use crate::services::filter::{FilterChangeset, FilterMap, FilterResult, FilterResultNotification, FilterType};
use crate::services::row::GridBlockRowRevision;
@ -352,7 +352,7 @@ fn filter_cell(
filter_map: &FilterMap,
cell_rev: Option<&CellRevision>,
) -> Option<bool> {
let any_cell_data = match cell_rev {
let type_cell_data = match cell_rev {
None => TypeCellData::from_field_type(&filter_id.field_type),
Some(cell_rev) => match TypeCellData::try_from(cell_rev) {
Ok(cell_data) => cell_data,
@ -362,13 +362,13 @@ fn filter_cell(
}
},
};
let cloned_cell_data = any_cell_data.data.clone();
let cloned_type_cell_data = type_cell_data.data.clone();
let is_visible = match &filter_id.field_type {
FieldType::RichText => filter_map.text_filter.get(filter_id).and_then(|filter| {
Some(
field_rev
.get_type_option::<RichTextTypeOptionPB>(field_rev.ty)?
.apply_filter(any_cell_data, filter)
.apply_filter(type_cell_data, filter)
.ok(),
)
}),
@ -376,7 +376,7 @@ fn filter_cell(
Some(
field_rev
.get_type_option::<NumberTypeOptionPB>(field_rev.ty)?
.apply_filter(any_cell_data, filter)
.apply_filter(type_cell_data, filter)
.ok(),
)
}),
@ -384,7 +384,7 @@ fn filter_cell(
Some(
field_rev
.get_type_option::<DateTypeOptionPB>(field_rev.ty)?
.apply_filter(any_cell_data, filter)
.apply_filter(type_cell_data, filter)
.ok(),
)
}),
@ -392,7 +392,7 @@ fn filter_cell(
Some(
field_rev
.get_type_option::<SingleSelectTypeOptionPB>(field_rev.ty)?
.apply_filter(any_cell_data, filter)
.apply_filter(type_cell_data, filter)
.ok(),
)
}),
@ -400,7 +400,7 @@ fn filter_cell(
Some(
field_rev
.get_type_option::<MultiSelectTypeOptionPB>(field_rev.ty)?
.apply_filter(any_cell_data, filter)
.apply_filter(type_cell_data, filter)
.ok(),
)
}),
@ -408,7 +408,7 @@ fn filter_cell(
Some(
field_rev
.get_type_option::<CheckboxTypeOptionPB>(field_rev.ty)?
.apply_filter(any_cell_data, filter)
.apply_filter(type_cell_data, filter)
.ok(),
)
}),
@ -416,7 +416,7 @@ fn filter_cell(
Some(
field_rev
.get_type_option::<URLTypeOptionPB>(field_rev.ty)?
.apply_filter(any_cell_data, filter)
.apply_filter(type_cell_data, filter)
.ok(),
)
}),
@ -424,14 +424,14 @@ fn filter_cell(
Some(
field_rev
.get_type_option::<ChecklistTypeOptionPB>(field_rev.ty)?
.apply_filter(any_cell_data, filter)
.apply_filter(type_cell_data, filter)
.ok(),
)
}),
}?;
tracing::Span::current().record(
"cell_content",
&format!("{} => {:?}", cloned_cell_data, is_visible.unwrap()).as_str(),
&format!("{} => {:?}", cloned_type_cell_data, is_visible.unwrap()).as_str(),
);
is_visible
}

View File

@ -71,9 +71,9 @@ pub struct FilterType {
pub field_type: FieldType,
}
impl Into<FieldTypeRevision> for FilterType {
fn into(self) -> FieldTypeRevision {
self.field_type.into()
impl From<FilterType> for FieldTypeRevision {
fn from(filter_type: FilterType) -> Self {
filter_type.field_type.into()
}
}
impl std::convert::From<&Arc<FieldRevision>> for FilterType {

View File

@ -3,7 +3,7 @@ use crate::entities::CellPathParams;
use crate::entities::*;
use crate::manager::GridUser;
use crate::services::block_manager::GridBlockManager;
use crate::services::cell::{apply_cell_data_changeset, decode_any_cell_data, CellBytes};
use crate::services::cell::{apply_cell_data_changeset, decode_type_cell_data, CellBytes};
use crate::services::field::{
default_type_option_builder_from_type, type_option_builder_from_bytes, type_option_builder_from_json_str,
FieldBuilder,
@ -431,20 +431,20 @@ impl GridRevisionEditor {
}
pub async fn get_cell(&self, params: &CellPathParams) -> Option<CellPB> {
let (field_type, cell_bytes) = self.decode_any_cell_data(params).await?;
let (field_type, cell_bytes) = self.decode_cell_data_from(params).await?;
Some(CellPB::new(&params.field_id, field_type, cell_bytes.to_vec()))
}
pub async fn get_cell_bytes(&self, params: &CellPathParams) -> Option<CellBytes> {
let (_, cell_data) = self.decode_any_cell_data(params).await?;
let (_, cell_data) = self.decode_cell_data_from(params).await?;
Some(cell_data)
}
async fn decode_any_cell_data(&self, params: &CellPathParams) -> Option<(FieldType, CellBytes)> {
async fn decode_cell_data_from(&self, params: &CellPathParams) -> Option<(FieldType, CellBytes)> {
let field_rev = self.get_field_rev(&params.field_id).await?;
let (_, row_rev) = self.block_manager.get_row_rev(&params.row_id).await.ok()??;
let cell_rev = row_rev.cells.get(&params.field_id)?.clone();
Some(decode_any_cell_data(cell_rev.data, &field_rev))
Some(decode_type_cell_data(cell_rev.data, &field_rev))
}
pub async fn get_cell_rev(&self, row_id: &str, field_id: &str) -> FlowyResult<Option<CellRevision>> {

View File

@ -1,5 +1,5 @@
use crate::entities::{GroupRowsNotificationPB, GroupViewChangesetPB, InsertedRowPB, RowPB};
use crate::services::cell::{decode_any_cell_data, CellBytesParser, CellDataIsEmpty};
use crate::services::cell::{decode_type_cell_data, CellBytesParser, CellDataIsEmpty};
use crate::services::group::action::{GroupControllerCustomActions, GroupControllerSharedActions};
use crate::services::group::configuration::GroupContext;
use crate::services::group::entities::Group;
@ -184,7 +184,7 @@ where
if let Some(cell_rev) = cell_rev {
let mut grouped_rows: Vec<GroupedRow> = vec![];
let cell_bytes = decode_any_cell_data(cell_rev.data, field_rev).1;
let cell_bytes = decode_type_cell_data(cell_rev.data, field_rev).1;
let cell_data = cell_bytes.parser::<P>()?;
for group in self.group_ctx.groups() {
if self.can_group(&group.filter_content, &cell_data) {
@ -224,7 +224,7 @@ where
field_rev: &FieldRevision,
) -> FlowyResult<Vec<GroupRowsNotificationPB>> {
if let Some(cell_rev) = row_rev.cells.get(&self.field_id) {
let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev).1;
let cell_bytes = decode_type_cell_data(cell_rev.data.clone(), field_rev).1;
let cell_data = cell_bytes.parser::<P>()?;
let mut changesets = self.add_or_remove_row_in_groups_if_match(row_rev, &cell_data);
@ -247,7 +247,7 @@ where
) -> FlowyResult<Vec<GroupRowsNotificationPB>> {
// if the cell_rev is none, then the row must in the default group.
if let Some(cell_rev) = row_rev.cells.get(&self.field_id) {
let cell_bytes = decode_any_cell_data(cell_rev.data.clone(), field_rev).1;
let cell_bytes = decode_type_cell_data(cell_rev.data.clone(), field_rev).1;
let cell_data = cell_bytes.parser::<P>()?;
if !cell_data.is_empty() {
tracing::error!("did_delete_delete_row {:?}", cell_rev.data);
@ -280,7 +280,7 @@ where
};
if let Some(cell_rev) = cell_rev {
let cell_bytes = decode_any_cell_data(cell_rev.data, context.field_rev).1;
let cell_bytes = decode_type_cell_data(cell_rev.data, context.field_rev).1;
let cell_data = cell_bytes.parser::<P>()?;
Ok(self.move_row(&cell_data, context))
} else {

View File

@ -1,3 +1,5 @@
#![allow(clippy::all)]
#[allow(unused_attributes)]
use crate::entities::{GridSortPB, SortChangesetNotificationPB};
use crate::services::sort::{SortChangeset, SortType};
use flowy_task::TaskDispatcher;
@ -13,10 +15,14 @@ pub trait SortDelegate: Send + Sync {
}
pub struct SortController {
#[allow(dead_code)]
view_id: String,
#[allow(dead_code)]
handler_id: String,
#[allow(dead_code)]
delegate: Box<dyn SortDelegate>,
task_scheduler: Arc<RwLock<TaskDispatcher>>,
#[allow(dead_code)]
sorts: Vec<GridSortPB>,
}
@ -42,11 +48,11 @@ impl SortController {
.await;
}
pub fn sort_rows(&self, rows: &mut Vec<Arc<RowRevision>>) {
todo!()
pub fn sort_rows(&self, _rows: &mut Vec<Arc<RowRevision>>) {
//
}
pub async fn did_receive_changes(&self, changeset: SortChangeset) -> Option<SortChangesetNotificationPB> {
todo!()
pub async fn did_receive_changes(&mut self, _changeset: SortChangeset) -> Option<SortChangesetNotificationPB> {
None
}
}

View File

@ -8,9 +8,9 @@ pub struct SortType {
pub field_type: FieldType,
}
impl Into<FieldTypeRevision> for SortType {
fn into(self) -> FieldTypeRevision {
self.field_type.into()
impl From<SortType> for FieldTypeRevision {
fn from(sort_type: SortType) -> Self {
sort_type.field_type.into()
}
}
@ -32,6 +32,7 @@ impl std::convert::From<&Arc<FieldRevision>> for SortType {
}
}
#[allow(dead_code)]
#[derive(Debug)]
pub struct SortChangeset {
pub(crate) insert_sort: Option<SortType>,

View File

@ -6,6 +6,7 @@ use tokio::sync::RwLock;
pub struct SortTaskHandler {
handler_id: String,
#[allow(dead_code)]
sort_controller: Arc<RwLock<SortController>>,
}
@ -23,7 +24,7 @@ impl TaskHandler for SortTaskHandler {
&self.handler_id
}
fn run(&self, content: TaskContent) -> BoxResultFuture<(), anyhow::Error> {
fn run(&self, _content: TaskContent) -> BoxResultFuture<(), anyhow::Error> {
todo!();
}
}

View File

@ -417,7 +417,7 @@ impl GridViewRevisionEditor {
}
pub async fn delete_view_sort(&self, params: DeleteSortParams) -> FlowyResult<()> {
let sort_type = SortType::from(&params);
let sort_type = params.sort_type;
let changeset = self
.sort_controller
.write()

View File

@ -99,7 +99,7 @@ impl GridFilterTest {
}
}
fn view_id(&self) -> String {
pub fn view_id(&self) -> String {
self.grid_id.clone()
}
@ -134,7 +134,7 @@ impl GridFilterTest {
};
let payload =
AlterFilterPayloadPB::new(
view_id: self.view_id(),
& self.view_id(),
field_rev, text_filter);
self.insert_filter(payload).await;
}
@ -157,7 +157,7 @@ impl GridFilterTest {
};
let payload =
AlterFilterPayloadPB::new(
view_id: self.view_id(),
&self.view_id(),
field_rev, number_filter);
self.insert_filter(payload).await;
}
@ -167,7 +167,7 @@ impl GridFilterTest {
condition
};
let payload =
AlterFilterPayloadPB::new(view_id: self.view_id(), field_rev, checkbox_filter);
AlterFilterPayloadPB::new(& self.view_id(), field_rev, checkbox_filter);
self.insert_filter(payload).await;
}
FilterScript::CreateDateFilter { condition, start, end, timestamp} => {
@ -180,21 +180,21 @@ impl GridFilterTest {
};
let payload =
AlterFilterPayloadPB::new(view_id: self.view_id(), field_rev, date_filter);
AlterFilterPayloadPB::new( &self.view_id(), field_rev, date_filter);
self.insert_filter(payload).await;
}
FilterScript::CreateMultiSelectFilter { condition, option_ids} => {
let field_rev = self.get_first_field_rev(FieldType::MultiSelect);
let filter = SelectOptionFilterPB { condition, option_ids };
let payload =
AlterFilterPayloadPB::new(view_id: self.view_id(),field_rev, filter);
AlterFilterPayloadPB::new( &self.view_id(),field_rev, filter);
self.insert_filter(payload).await;
}
FilterScript::CreateSingleSelectFilter { condition, option_ids} => {
let field_rev = self.get_first_field_rev(FieldType::SingleSelect);
let filter = SelectOptionFilterPB { condition, option_ids };
let payload =
AlterFilterPayloadPB::new(view_id: self.view_id(),field_rev, filter);
AlterFilterPayloadPB::new(& self.view_id(),field_rev, filter);
self.insert_filter(payload).await;
}
FilterScript::CreateChecklistFilter { condition} => {
@ -202,7 +202,7 @@ impl GridFilterTest {
// let type_option = self.get_checklist_type_option(&field_rev.id);
let filter = ChecklistFilterPB { condition };
let payload =
AlterFilterPayloadPB::new(view_id: self.view_id(),field_rev, filter);
AlterFilterPayloadPB::new(& self.view_id(),field_rev, filter);
self.insert_filter(payload).await;
}
FilterScript::AssertFilterCount { count } => {

View File

@ -189,7 +189,7 @@ async fn grid_filter_delete_test() {
condition: TextFilterConditionPB::TextIsEmpty,
content: "".to_string(),
};
let payload = AlterFilterPayloadPB::new(&field_rev, text_filter);
let payload = AlterFilterPayloadPB::new(&test.view_id(), &field_rev, text_filter);
let scripts = vec![
InsertFilter { payload },
AssertFilterCount { count: 1 },

View File

@ -2,7 +2,6 @@ use crate::{FieldRevision, FieldTypeRevision, FilterRevision, GroupConfiguration
use indexmap::IndexMap;
use nanoid::nanoid;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fmt::Debug;
use std::sync::Arc;

View File

@ -85,7 +85,7 @@ mod tests {
let s = serde_json::to_string(&grid_view_revision).unwrap();
assert_eq!(
s,
r#"{"view_id":"1","grid_id":"1","layout":0,"filters":[],"groups":[]}"#
r#"{"view_id":"1","grid_id":"1","layout":0,"filters":[],"groups":[],"sorts":[]}"#
);
}
}