|
@@ -1,13 +1,12 @@
|
|
|
-use crate::entities::FieldType;
|
|
|
-use crate::services::field::*;
|
|
|
-use bytes::Bytes;
|
|
|
-use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult};
|
|
|
+use flowy_error::{ErrorCode, FlowyError, FlowyResult};
|
|
|
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, FieldTypeRevision};
|
|
|
-use serde::{Deserialize, Serialize};
|
|
|
|
|
|
-use std::str::FromStr;
|
|
|
+use crate::entities::FieldType;
|
|
|
+use crate::services::cell::{AnyCellData, DecodedCellData};
|
|
|
+use crate::services::field::*;
|
|
|
|
|
|
pub trait CellFilterOperation<T> {
|
|
|
+ /// Return true if any_cell_data match the filter condition.
|
|
|
fn apply_filter(&self, any_cell_data: AnyCellData, filter: &T) -> FlowyResult<bool>;
|
|
|
}
|
|
|
|
|
@@ -27,105 +26,6 @@ pub trait CellDataOperation<D, C> {
|
|
|
/// SelectOptionCellChangeset,DateCellChangeset. etc.
|
|
|
fn apply_changeset(&self, changeset: CellDataChangeset<C>, cell_rev: Option<CellRevision>) -> FlowyResult<String>;
|
|
|
}
|
|
|
-
|
|
|
-/// AnyCellData 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.
|
|
|
-/// So it will return an empty data. You could check the CellDataOperation trait for more information.
|
|
|
-#[derive(Debug, Serialize, Deserialize)]
|
|
|
-pub struct AnyCellData {
|
|
|
- pub cell_data: String,
|
|
|
- pub field_type: FieldType,
|
|
|
-}
|
|
|
-
|
|
|
-impl std::str::FromStr for AnyCellData {
|
|
|
- type Err = FlowyError;
|
|
|
-
|
|
|
- fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
|
- let type_option_cell_data: AnyCellData = serde_json::from_str(s)?;
|
|
|
- Ok(type_option_cell_data)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl std::convert::TryInto<AnyCellData> for String {
|
|
|
- type Error = FlowyError;
|
|
|
-
|
|
|
- fn try_into(self) -> Result<AnyCellData, Self::Error> {
|
|
|
- AnyCellData::from_str(&self)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl std::convert::TryFrom<&CellRevision> for AnyCellData {
|
|
|
- type Error = FlowyError;
|
|
|
-
|
|
|
- fn try_from(value: &CellRevision) -> Result<Self, Self::Error> {
|
|
|
- Self::from_str(&value.data)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl std::convert::TryFrom<&Option<CellRevision>> for AnyCellData {
|
|
|
- type Error = FlowyError;
|
|
|
-
|
|
|
- fn try_from(value: &Option<CellRevision>) -> Result<Self, Self::Error> {
|
|
|
- match value {
|
|
|
- None => Err(FlowyError::invalid_data().context("Expected CellRevision, but receive None")),
|
|
|
- Some(cell_rev) => AnyCellData::try_from(cell_rev),
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl std::convert::TryFrom<Option<CellRevision>> for AnyCellData {
|
|
|
- type Error = FlowyError;
|
|
|
-
|
|
|
- fn try_from(value: Option<CellRevision>) -> Result<Self, Self::Error> {
|
|
|
- Self::try_from(&value)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl AnyCellData {
|
|
|
- pub fn new(content: String, field_type: FieldType) -> Self {
|
|
|
- AnyCellData {
|
|
|
- cell_data: content,
|
|
|
- field_type,
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- pub fn json(&self) -> String {
|
|
|
- serde_json::to_string(self).unwrap_or_else(|_| "".to_owned())
|
|
|
- }
|
|
|
-
|
|
|
- pub fn is_number(&self) -> bool {
|
|
|
- self.field_type == FieldType::Number
|
|
|
- }
|
|
|
-
|
|
|
- pub fn is_text(&self) -> bool {
|
|
|
- self.field_type == FieldType::RichText
|
|
|
- }
|
|
|
-
|
|
|
- pub fn is_checkbox(&self) -> bool {
|
|
|
- self.field_type == FieldType::Checkbox
|
|
|
- }
|
|
|
-
|
|
|
- pub fn is_date(&self) -> bool {
|
|
|
- self.field_type == FieldType::DateTime
|
|
|
- }
|
|
|
-
|
|
|
- pub fn is_single_select(&self) -> bool {
|
|
|
- self.field_type == FieldType::SingleSelect
|
|
|
- }
|
|
|
-
|
|
|
- pub fn is_multi_select(&self) -> bool {
|
|
|
- self.field_type == FieldType::MultiSelect
|
|
|
- }
|
|
|
-
|
|
|
- pub fn is_url(&self) -> bool {
|
|
|
- self.field_type == FieldType::URL
|
|
|
- }
|
|
|
-
|
|
|
- pub fn is_select_option(&self) -> bool {
|
|
|
- self.field_type == FieldType::MultiSelect || self.field_type == FieldType::SingleSelect
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
/// The changeset will be deserialized into specific data base on the FieldType.
|
|
|
/// For example, it's String on FieldType::RichText, and SelectOptionChangeset on FieldType::SingleSelect
|
|
|
pub fn apply_cell_data_changeset<C: ToString, T: AsRef<FieldRevision>>(
|
|
@@ -292,51 +192,3 @@ impl std::convert::From<String> for CellDataChangeset<String> {
|
|
|
CellDataChangeset(Some(s))
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-/// The data is encoded by protobuf or utf8. You should choose the corresponding decode struct to parse it.
|
|
|
-///
|
|
|
-/// For example:
|
|
|
-///
|
|
|
-/// * Use DateCellData to parse the data when the FieldType is Date.
|
|
|
-/// * Use URLCellData to parse the data when the FieldType is URL.
|
|
|
-/// * Use String to parse the data when the FieldType is RichText, Number, or Checkbox.
|
|
|
-/// * Check out the implementation of CellDataOperation trait for more information.
|
|
|
-#[derive(Default)]
|
|
|
-pub struct DecodedCellData {
|
|
|
- pub data: Vec<u8>,
|
|
|
-}
|
|
|
-
|
|
|
-impl DecodedCellData {
|
|
|
- pub fn new<T: AsRef<[u8]>>(data: T) -> Self {
|
|
|
- Self {
|
|
|
- data: data.as_ref().to_vec(),
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- pub fn try_from_bytes<T: TryInto<Bytes>>(bytes: T) -> FlowyResult<Self>
|
|
|
- where
|
|
|
- <T as TryInto<Bytes>>::Error: std::fmt::Debug,
|
|
|
- {
|
|
|
- let bytes = bytes.try_into().map_err(internal_error)?;
|
|
|
- Ok(Self { data: bytes.to_vec() })
|
|
|
- }
|
|
|
-
|
|
|
- pub fn parse<'a, T: TryFrom<&'a [u8]>>(&'a self) -> FlowyResult<T>
|
|
|
- where
|
|
|
- <T as TryFrom<&'a [u8]>>::Error: std::fmt::Debug,
|
|
|
- {
|
|
|
- T::try_from(self.data.as_ref()).map_err(internal_error)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl ToString for DecodedCellData {
|
|
|
- fn to_string(&self) -> String {
|
|
|
- match String::from_utf8(self.data.clone()) {
|
|
|
- Ok(s) => s,
|
|
|
- Err(e) => {
|
|
|
- tracing::error!("DecodedCellData to string failed: {:?}", e);
|
|
|
- "".to_string()
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|