chore: type option cell data trait cleanup (#4782)

* chore: remove dead code

* chore: remove legacy FromCellStringTrait
This commit is contained in:
Richard Shiue 2024-02-29 15:48:06 +08:00 committed by GitHub
parent f4ca3ef782
commit 682bf19838
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 41 additions and 265 deletions

View File

@ -1,3 +1,5 @@
use std::str::FromStr;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::ErrorCode;
@ -48,7 +50,7 @@ impl FromFilterString for SelectOptionFilterPB {
where
Self: Sized,
{
let ids = SelectOptionIds::from(filter.content.clone());
let ids = SelectOptionIds::from_str(&filter.content).unwrap_or_default();
SelectOptionFilterPB {
condition: SelectOptionConditionPB::try_from(filter.condition as u8)
.unwrap_or(SelectOptionConditionPB::OptionIs),
@ -59,7 +61,7 @@ impl FromFilterString for SelectOptionFilterPB {
impl std::convert::From<&Filter> for SelectOptionFilterPB {
fn from(filter: &Filter) -> Self {
let ids = SelectOptionIds::from(filter.content.clone());
let ids = SelectOptionIds::from_str(&filter.content).unwrap_or_default();
SelectOptionFilterPB {
condition: SelectOptionConditionPB::try_from(filter.condition as u8)
.unwrap_or(SelectOptionConditionPB::OptionIs),

View File

@ -1,4 +1,5 @@
use std::collections::HashMap;
use std::str::FromStr;
use collab_database::fields::Field;
use collab_database::rows::{get_field_type_from_cell, Cell, Cells};
@ -245,13 +246,6 @@ pub fn delete_select_option_cell(option_ids: Vec<String>, field: &Field) -> Cell
apply_cell_changeset(BoxAny::new(changeset), None, field, None).unwrap()
}
/// Deserialize the String into cell specific data type.
pub trait FromCellString {
fn from_cell_str(s: &str) -> FlowyResult<Self>
where
Self: Sized;
}
pub struct CellBuilder<'a> {
cells: Cells,
field_maps: HashMap<String, &'a Field>,
@ -290,12 +284,12 @@ impl<'a> CellBuilder<'a> {
tracing::warn!("Shouldn't insert cell data to cell whose field type is LastEditedTime or CreatedTime");
},
FieldType::SingleSelect | FieldType::MultiSelect => {
if let Ok(ids) = SelectOptionIds::from_cell_str(&cell_str) {
if let Ok(ids) = SelectOptionIds::from_str(&cell_str) {
cells.insert(field_id, insert_select_option_cell(ids.into_inner(), field));
}
},
FieldType::Checkbox => {
if let Ok(value) = CheckboxCellDataPB::from_cell_str(&cell_str) {
if let Ok(value) = CheckboxCellDataPB::from_str(&cell_str) {
cells.insert(field_id, insert_checkbox_cell(value.is_checked, field));
}
},
@ -303,7 +297,7 @@ impl<'a> CellBuilder<'a> {
cells.insert(field_id, insert_url_cell(cell_str, field));
},
FieldType::Checklist => {
if let Ok(ids) = SelectOptionIds::from_cell_str(&cell_str) {
if let Ok(ids) = SelectOptionIds::from_str(&cell_str) {
cells.insert(field_id, insert_select_option_cell(ids.into_inner(), field));
}
},

View File

@ -1,109 +1,6 @@
use bytes::Bytes;
use serde::{Deserialize, Serialize};
use flowy_error::{internal_error, FlowyError, FlowyResult};
use crate::entities::FieldType;
/// TypeCellData is a generic CellData, you can parse the type_cell_data according to the field_type.
/// The `data` is encoded by JSON format. You can use `IntoCellData` to decode the opaque data to
/// concrete cell type.
/// TypeCellData -> IntoCellData<T> -> T
///
/// The `TypeCellData` is the same as the cell data that was saved to disk except it carries the
/// field_type. The field_type indicates the cell data original `FieldType`. The field_type will
/// be changed if the current Field's type switch from one to another.
///
#[derive(Debug, Serialize, Deserialize)]
pub struct TypeCellData {
#[serde(rename = "data")]
pub cell_str: String,
pub field_type: FieldType,
}
impl TypeCellData {
pub fn from_field_type(field_type: &FieldType) -> TypeCellData {
Self {
cell_str: "".to_string(),
field_type: *field_type,
}
}
pub fn from_json_str(s: &str) -> FlowyResult<Self> {
let type_cell_data: TypeCellData = serde_json::from_str(s).map_err(|err| {
let msg = format!("Deserialize {} to type cell data failed.{}", s, err);
FlowyError::internal().with_context(msg)
})?;
Ok(type_cell_data)
}
pub fn into_inner(self) -> String {
self.cell_str
}
}
impl std::convert::TryFrom<String> for TypeCellData {
type Error = FlowyError;
fn try_from(value: String) -> Result<Self, Self::Error> {
TypeCellData::from_json_str(&value)
}
}
impl ToString for TypeCellData {
fn to_string(&self) -> String {
self.cell_str.clone()
}
}
impl TypeCellData {
pub fn new(cell_str: String, field_type: FieldType) -> Self {
TypeCellData {
cell_str,
field_type,
}
}
pub fn to_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_checklist(&self) -> bool {
self.field_type == FieldType::Checklist
}
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
}
}
use flowy_error::{internal_error, FlowyResult};
/// The data is encoded by protobuf or utf8. You should choose the corresponding decode struct to parse it.
///
@ -116,13 +13,8 @@ impl TypeCellData {
#[derive(Default, Debug)]
pub struct CellProtobufBlob(pub Bytes);
pub trait DecodedCellData {
type Object;
fn is_empty(&self) -> bool;
}
pub trait CellProtobufBlobParser {
type Object: DecodedCellData;
type Object;
fn parser(bytes: &Bytes) -> FlowyResult<Self::Object>;
}

View File

@ -1,11 +1,12 @@
#[cfg(test)]
mod tests {
use std::str::FromStr;
use collab_database::fields::Field;
use crate::entities::CheckboxCellDataPB;
use crate::entities::FieldType;
use crate::services::cell::CellDataDecoder;
use crate::services::cell::FromCellString;
use crate::services::field::type_options::checkbox_type_option::*;
use crate::services::field::FieldBuilder;
@ -43,7 +44,7 @@ mod tests {
assert_eq!(
type_option
.decode_cell(
&CheckboxCellDataPB::from_cell_str(input_str).unwrap().into(),
&CheckboxCellDataPB::from_str(input_str).unwrap().into(),
field_type,
field
)

View File

@ -7,7 +7,7 @@ use collab_database::rows::{new_cell_builder, Cell};
use flowy_error::{FlowyError, FlowyResult};
use crate::entities::{CheckboxCellDataPB, FieldType};
use crate::services::cell::{CellProtobufBlobParser, DecodedCellData, FromCellString};
use crate::services::cell::CellProtobufBlobParser;
use crate::services::field::{TypeOptionCellData, CELL_DATA};
pub const CHECK: &str = "Yes";
@ -22,7 +22,7 @@ impl TypeOptionCellData for CheckboxCellDataPB {
impl From<&Cell> for CheckboxCellDataPB {
fn from(cell: &Cell) -> Self {
let value = cell.get_str_value(CELL_DATA).unwrap_or_default();
CheckboxCellDataPB::from_cell_str(&value).unwrap_or_default()
CheckboxCellDataPB::from_str(&value).unwrap_or_default()
}
}
@ -49,15 +49,6 @@ impl FromStr for CheckboxCellDataPB {
}
}
impl FromCellString for CheckboxCellDataPB {
fn from_cell_str(s: &str) -> FlowyResult<Self>
where
Self: Sized,
{
Self::from_str(s)
}
}
impl ToString for CheckboxCellDataPB {
fn to_string(&self) -> String {
if self.is_checked {
@ -68,14 +59,6 @@ impl ToString for CheckboxCellDataPB {
}
}
impl DecodedCellData for CheckboxCellDataPB {
type Object = CheckboxCellDataPB;
fn is_empty(&self) -> bool {
false
}
}
pub struct CheckboxCellDataParser();
impl CellProtobufBlobParser for CheckboxCellDataParser {
type Object = CheckboxCellDataPB;

View File

@ -11,7 +11,7 @@ use strum_macros::EnumIter;
use flowy_error::{internal_error, FlowyResult};
use crate::entities::{DateCellDataPB, FieldType};
use crate::services::cell::{CellProtobufBlobParser, DecodedCellData, FromCellString};
use crate::services::cell::CellProtobufBlobParser;
use crate::services::field::{TypeOptionCellData, CELL_DATA};
#[derive(Clone, Debug, Default)]
@ -196,16 +196,6 @@ impl<'de> serde::Deserialize<'de> for DateCellData {
}
}
impl FromCellString for DateCellData {
fn from_cell_str(s: &str) -> FlowyResult<Self>
where
Self: Sized,
{
let result: DateCellData = serde_json::from_str(s).unwrap();
Ok(result)
}
}
impl ToString for DateCellData {
fn to_string(&self) -> String {
serde_json::to_string(self).unwrap()
@ -288,14 +278,6 @@ impl TimeFormat {
}
}
impl DecodedCellData for DateCellDataPB {
type Object = DateCellDataPB;
fn is_empty(&self) -> bool {
self.date.is_empty()
}
}
pub struct DateCellDataParser();
impl CellProtobufBlobParser for DateCellDataParser {
type Object = DateCellDataPB;

View File

@ -1,4 +1,4 @@
use crate::services::cell::{CellBytesCustomParser, CellProtobufBlobParser, DecodedCellData};
use crate::services::cell::{CellBytesCustomParser, CellProtobufBlobParser};
use crate::services::field::number_currency::Currency;
use crate::services::field::{NumberFormat, EXTRACT_NUM_REGEX, START_WITH_DOT_NUM_REGEX};
use bytes::Bytes;
@ -108,14 +108,6 @@ impl ToString for NumberCellFormat {
}
}
impl DecodedCellData for NumberCellFormat {
type Object = NumberCellFormat;
fn is_empty(&self) -> bool {
self.decimal.is_none()
}
}
pub struct NumberCellDataParser();
impl CellProtobufBlobParser for NumberCellDataParser {
type Object = NumberCellFormat;

View File

@ -216,8 +216,6 @@ mod tests {
debug_assert_eq!(multi_select.options.len(), 2);
}
// #[test]
#[test]
fn multi_select_insert_multi_option_test() {
let google = SelectOption::new("Google");

View File

@ -1,10 +1,11 @@
use std::str::FromStr;
use collab::core::any_map::AnyMapExtension;
use collab_database::rows::{new_cell_builder, Cell};
use flowy_error::FlowyResult;
use flowy_error::FlowyError;
use crate::entities::FieldType;
use crate::services::cell::{DecodedCellData, FromCellString};
use crate::services::field::{TypeOptionCellData, CELL_DATA};
pub const SELECTION_IDS_SEPARATOR: &str = ",";
@ -37,33 +38,25 @@ impl TypeOptionCellData for SelectOptionIds {
}
}
impl FromCellString for SelectOptionIds {
fn from_cell_str(s: &str) -> FlowyResult<Self>
where
Self: Sized,
{
Ok(Self::from(s.to_owned()))
}
}
impl From<&Cell> for SelectOptionIds {
fn from(cell: &Cell) -> Self {
let value = cell.get_str_value(CELL_DATA).unwrap_or_default();
Self::from(value)
Self::from_str(&value).unwrap_or_default()
}
}
impl std::convert::From<String> for SelectOptionIds {
fn from(s: String) -> Self {
if s.is_empty() {
return Self(vec![]);
}
impl FromStr for SelectOptionIds {
type Err = FlowyError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.is_empty() {
return Ok(Self(vec![]));
}
let ids = s
.split(SELECTION_IDS_SEPARATOR)
.map(|id| id.to_string())
.collect::<Vec<String>>();
Self(ids)
Ok(Self(ids))
}
}
@ -89,7 +82,7 @@ impl std::convert::From<Option<String>> for SelectOptionIds {
fn from(s: Option<String>) -> Self {
match s {
None => Self(vec![]),
Some(s) => Self::from(s),
Some(s) => Self::from_str(&s).unwrap_or_default(),
}
}
}
@ -107,11 +100,3 @@ impl std::ops::DerefMut for SelectOptionIds {
&mut self.0
}
}
impl DecodedCellData for SelectOptionIds {
type Object = SelectOptionIds;
fn is_empty(&self) -> bool {
self.0.is_empty()
}
}

View File

@ -1,3 +1,5 @@
use std::str::FromStr;
use bytes::Bytes;
use collab_database::fields::{Field, TypeOptionData};
use collab_database::rows::Cell;
@ -5,7 +7,7 @@ use collab_database::rows::Cell;
use flowy_error::{internal_error, ErrorCode, FlowyResult};
use crate::entities::{CheckboxCellDataPB, FieldType, SelectOptionCellDataPB};
use crate::services::cell::{CellDataDecoder, CellProtobufBlobParser, DecodedCellData};
use crate::services::cell::{CellDataDecoder, CellProtobufBlobParser};
use crate::services::field::selection_type_option::type_option_transform::SelectOptionTypeOptionTransformHelper;
use crate::services::field::{
make_selected_options, MultiSelectTypeOption, SelectOption, SelectOptionCellData,
@ -205,20 +207,12 @@ impl CellProtobufBlobParser for SelectOptionIdsParser {
type Object = SelectOptionIds;
fn parser(bytes: &Bytes) -> FlowyResult<Self::Object> {
match String::from_utf8(bytes.to_vec()) {
Ok(s) => Ok(SelectOptionIds::from(s)),
Err(_) => Ok(SelectOptionIds::from("".to_owned())),
Ok(s) => SelectOptionIds::from_str(&s),
Err(_) => Ok(SelectOptionIds::default()),
}
}
}
impl DecodedCellData for SelectOptionCellDataPB {
type Object = SelectOptionCellDataPB;
fn is_empty(&self) -> bool {
self.select_options.is_empty()
}
}
pub struct SelectOptionCellDataParser();
impl CellProtobufBlobParser for SelectOptionCellDataParser {
type Object = SelectOptionCellDataPB;

View File

@ -10,8 +10,7 @@ use flowy_error::{FlowyError, FlowyResult};
use crate::entities::{FieldType, TextFilterPB};
use crate::services::cell::{
stringify_cell_data, CellDataChangeset, CellDataDecoder, CellProtobufBlobParser, DecodedCellData,
FromCellString,
stringify_cell_data, CellDataChangeset, CellDataDecoder, CellProtobufBlobParser,
};
use crate::services::field::type_options::util::ProtobufStr;
use crate::services::field::{
@ -191,29 +190,12 @@ impl std::ops::Deref for TextCellData {
}
}
impl FromCellString for TextCellData {
fn from_cell_str(s: &str) -> FlowyResult<Self>
where
Self: Sized,
{
Ok(TextCellData(s.to_owned()))
}
}
impl ToString for TextCellData {
fn to_string(&self) -> String {
self.0.clone()
}
}
impl DecodedCellData for TextCellData {
type Object = TextCellData;
fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
pub struct TextCellDataParser();
impl CellProtobufBlobParser for TextCellDataParser {
type Object = TextCellData;
@ -261,12 +243,6 @@ impl std::ops::DerefMut for StrCellData {
}
}
impl FromCellString for StrCellData {
fn from_cell_str(s: &str) -> FlowyResult<Self> {
Ok(Self(s.to_owned()))
}
}
impl std::convert::From<String> for StrCellData {
fn from(s: String) -> Self {
Self(s)

View File

@ -23,17 +23,16 @@ use crate::services::filter::FromFilterString;
use crate::services::sort::SortCondition;
pub trait TypeOption {
/// `CellData` represents as the decoded model for current type option. Each of them impl the
/// `FromCellString` and `Default` trait. If the cell string can not be decoded into the specified
/// cell data type then the default value will be returned.
/// For example:
/// `CellData` represents the decoded model for the current type option. Each of them must
/// implement the From<&Cell> trait. If the `Cell` cannot be decoded into this type, the default
/// value will be returned.
///
/// Note: Use `StrCellData` for any `TypeOption` whose cell data is simply `String`.
///
/// - FieldType::Checkbox => CheckboxCellData
/// - FieldType::Date => DateCellData
/// - FieldType::URL => URLCellData
///
/// Uses `StrCellData` for any `TypeOption` if their cell data is pure `String`.
///
type CellData: for<'a> From<&'a Cell>
+ TypeOptionCellData
+ ToString

View File

@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
use flowy_error::{internal_error, FlowyResult};
use crate::entities::{FieldType, URLCellDataPB};
use crate::services::cell::{CellProtobufBlobParser, DecodedCellData, FromCellString};
use crate::services::cell::CellProtobufBlobParser;
use crate::services::field::{TypeOptionCellData, CELL_DATA};
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
@ -60,14 +60,6 @@ impl From<URLCellData> for URLCellDataPB {
}
}
impl DecodedCellData for URLCellDataPB {
type Object = URLCellDataPB;
fn is_empty(&self) -> bool {
self.content.is_empty()
}
}
impl From<URLCellDataPB> for URLCellData {
fn from(data: URLCellDataPB) -> Self {
Self {
@ -83,14 +75,6 @@ impl AsRef<str> for URLCellData {
}
}
impl DecodedCellData for URLCellData {
type Object = URLCellData;
fn is_empty(&self) -> bool {
self.data.is_empty()
}
}
pub struct URLCellDataParser();
impl CellProtobufBlobParser for URLCellDataParser {
type Object = URLCellDataPB;
@ -100,12 +84,6 @@ impl CellProtobufBlobParser for URLCellDataParser {
}
}
impl FromCellString for URLCellData {
fn from_cell_str(s: &str) -> FlowyResult<Self> {
serde_json::from_str::<URLCellData>(s).map_err(internal_error)
}
}
impl ToString for URLCellData {
fn to_string(&self) -> String {
self.to_json().unwrap()