mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: type option cell data trait cleanup (#4782)
* chore: remove dead code * chore: remove legacy FromCellStringTrait
This commit is contained in:
parent
f4ca3ef782
commit
682bf19838
@ -1,3 +1,5 @@
|
|||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||||
use flowy_error::ErrorCode;
|
use flowy_error::ErrorCode;
|
||||||
|
|
||||||
@ -48,7 +50,7 @@ impl FromFilterString for SelectOptionFilterPB {
|
|||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
let ids = SelectOptionIds::from(filter.content.clone());
|
let ids = SelectOptionIds::from_str(&filter.content).unwrap_or_default();
|
||||||
SelectOptionFilterPB {
|
SelectOptionFilterPB {
|
||||||
condition: SelectOptionConditionPB::try_from(filter.condition as u8)
|
condition: SelectOptionConditionPB::try_from(filter.condition as u8)
|
||||||
.unwrap_or(SelectOptionConditionPB::OptionIs),
|
.unwrap_or(SelectOptionConditionPB::OptionIs),
|
||||||
@ -59,7 +61,7 @@ impl FromFilterString for SelectOptionFilterPB {
|
|||||||
|
|
||||||
impl std::convert::From<&Filter> for SelectOptionFilterPB {
|
impl std::convert::From<&Filter> for SelectOptionFilterPB {
|
||||||
fn from(filter: &Filter) -> Self {
|
fn from(filter: &Filter) -> Self {
|
||||||
let ids = SelectOptionIds::from(filter.content.clone());
|
let ids = SelectOptionIds::from_str(&filter.content).unwrap_or_default();
|
||||||
SelectOptionFilterPB {
|
SelectOptionFilterPB {
|
||||||
condition: SelectOptionConditionPB::try_from(filter.condition as u8)
|
condition: SelectOptionConditionPB::try_from(filter.condition as u8)
|
||||||
.unwrap_or(SelectOptionConditionPB::OptionIs),
|
.unwrap_or(SelectOptionConditionPB::OptionIs),
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use collab_database::fields::Field;
|
use collab_database::fields::Field;
|
||||||
use collab_database::rows::{get_field_type_from_cell, Cell, Cells};
|
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()
|
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> {
|
pub struct CellBuilder<'a> {
|
||||||
cells: Cells,
|
cells: Cells,
|
||||||
field_maps: HashMap<String, &'a Field>,
|
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");
|
tracing::warn!("Shouldn't insert cell data to cell whose field type is LastEditedTime or CreatedTime");
|
||||||
},
|
},
|
||||||
FieldType::SingleSelect | FieldType::MultiSelect => {
|
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));
|
cells.insert(field_id, insert_select_option_cell(ids.into_inner(), field));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
FieldType::Checkbox => {
|
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));
|
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));
|
cells.insert(field_id, insert_url_cell(cell_str, field));
|
||||||
},
|
},
|
||||||
FieldType::Checklist => {
|
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));
|
cells.insert(field_id, insert_select_option_cell(ids.into_inner(), field));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,109 +1,6 @@
|
|||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use flowy_error::{internal_error, FlowyError, FlowyResult};
|
use flowy_error::{internal_error, 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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.
|
||||||
///
|
///
|
||||||
@ -116,13 +13,8 @@ impl TypeCellData {
|
|||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct CellProtobufBlob(pub Bytes);
|
pub struct CellProtobufBlob(pub Bytes);
|
||||||
|
|
||||||
pub trait DecodedCellData {
|
|
||||||
type Object;
|
|
||||||
fn is_empty(&self) -> bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait CellProtobufBlobParser {
|
pub trait CellProtobufBlobParser {
|
||||||
type Object: DecodedCellData;
|
type Object;
|
||||||
fn parser(bytes: &Bytes) -> FlowyResult<Self::Object>;
|
fn parser(bytes: &Bytes) -> FlowyResult<Self::Object>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use collab_database::fields::Field;
|
use collab_database::fields::Field;
|
||||||
|
|
||||||
use crate::entities::CheckboxCellDataPB;
|
use crate::entities::CheckboxCellDataPB;
|
||||||
use crate::entities::FieldType;
|
use crate::entities::FieldType;
|
||||||
use crate::services::cell::CellDataDecoder;
|
use crate::services::cell::CellDataDecoder;
|
||||||
use crate::services::cell::FromCellString;
|
|
||||||
use crate::services::field::type_options::checkbox_type_option::*;
|
use crate::services::field::type_options::checkbox_type_option::*;
|
||||||
use crate::services::field::FieldBuilder;
|
use crate::services::field::FieldBuilder;
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
type_option
|
type_option
|
||||||
.decode_cell(
|
.decode_cell(
|
||||||
&CheckboxCellDataPB::from_cell_str(input_str).unwrap().into(),
|
&CheckboxCellDataPB::from_str(input_str).unwrap().into(),
|
||||||
field_type,
|
field_type,
|
||||||
field
|
field
|
||||||
)
|
)
|
||||||
|
@ -7,7 +7,7 @@ use collab_database::rows::{new_cell_builder, Cell};
|
|||||||
use flowy_error::{FlowyError, FlowyResult};
|
use flowy_error::{FlowyError, FlowyResult};
|
||||||
|
|
||||||
use crate::entities::{CheckboxCellDataPB, FieldType};
|
use crate::entities::{CheckboxCellDataPB, FieldType};
|
||||||
use crate::services::cell::{CellProtobufBlobParser, DecodedCellData, FromCellString};
|
use crate::services::cell::CellProtobufBlobParser;
|
||||||
use crate::services::field::{TypeOptionCellData, CELL_DATA};
|
use crate::services::field::{TypeOptionCellData, CELL_DATA};
|
||||||
|
|
||||||
pub const CHECK: &str = "Yes";
|
pub const CHECK: &str = "Yes";
|
||||||
@ -22,7 +22,7 @@ impl TypeOptionCellData for CheckboxCellDataPB {
|
|||||||
impl From<&Cell> for CheckboxCellDataPB {
|
impl From<&Cell> for CheckboxCellDataPB {
|
||||||
fn from(cell: &Cell) -> Self {
|
fn from(cell: &Cell) -> Self {
|
||||||
let value = cell.get_str_value(CELL_DATA).unwrap_or_default();
|
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 {
|
impl ToString for CheckboxCellDataPB {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
if self.is_checked {
|
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();
|
pub struct CheckboxCellDataParser();
|
||||||
impl CellProtobufBlobParser for CheckboxCellDataParser {
|
impl CellProtobufBlobParser for CheckboxCellDataParser {
|
||||||
type Object = CheckboxCellDataPB;
|
type Object = CheckboxCellDataPB;
|
||||||
|
@ -11,7 +11,7 @@ use strum_macros::EnumIter;
|
|||||||
use flowy_error::{internal_error, FlowyResult};
|
use flowy_error::{internal_error, FlowyResult};
|
||||||
|
|
||||||
use crate::entities::{DateCellDataPB, FieldType};
|
use crate::entities::{DateCellDataPB, FieldType};
|
||||||
use crate::services::cell::{CellProtobufBlobParser, DecodedCellData, FromCellString};
|
use crate::services::cell::CellProtobufBlobParser;
|
||||||
use crate::services::field::{TypeOptionCellData, CELL_DATA};
|
use crate::services::field::{TypeOptionCellData, CELL_DATA};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[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 {
|
impl ToString for DateCellData {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
serde_json::to_string(self).unwrap()
|
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();
|
pub struct DateCellDataParser();
|
||||||
impl CellProtobufBlobParser for DateCellDataParser {
|
impl CellProtobufBlobParser for DateCellDataParser {
|
||||||
type Object = DateCellDataPB;
|
type Object = DateCellDataPB;
|
||||||
|
@ -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::number_currency::Currency;
|
||||||
use crate::services::field::{NumberFormat, EXTRACT_NUM_REGEX, START_WITH_DOT_NUM_REGEX};
|
use crate::services::field::{NumberFormat, EXTRACT_NUM_REGEX, START_WITH_DOT_NUM_REGEX};
|
||||||
use bytes::Bytes;
|
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();
|
pub struct NumberCellDataParser();
|
||||||
impl CellProtobufBlobParser for NumberCellDataParser {
|
impl CellProtobufBlobParser for NumberCellDataParser {
|
||||||
type Object = NumberCellFormat;
|
type Object = NumberCellFormat;
|
||||||
|
@ -216,8 +216,6 @@ mod tests {
|
|||||||
debug_assert_eq!(multi_select.options.len(), 2);
|
debug_assert_eq!(multi_select.options.len(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multi_select_insert_multi_option_test() {
|
fn multi_select_insert_multi_option_test() {
|
||||||
let google = SelectOption::new("Google");
|
let google = SelectOption::new("Google");
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use collab::core::any_map::AnyMapExtension;
|
use collab::core::any_map::AnyMapExtension;
|
||||||
use collab_database::rows::{new_cell_builder, Cell};
|
use collab_database::rows::{new_cell_builder, Cell};
|
||||||
|
|
||||||
use flowy_error::FlowyResult;
|
use flowy_error::FlowyError;
|
||||||
|
|
||||||
use crate::entities::FieldType;
|
use crate::entities::FieldType;
|
||||||
use crate::services::cell::{DecodedCellData, FromCellString};
|
|
||||||
use crate::services::field::{TypeOptionCellData, CELL_DATA};
|
use crate::services::field::{TypeOptionCellData, CELL_DATA};
|
||||||
|
|
||||||
pub const SELECTION_IDS_SEPARATOR: &str = ",";
|
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 {
|
impl From<&Cell> for SelectOptionIds {
|
||||||
fn from(cell: &Cell) -> Self {
|
fn from(cell: &Cell) -> Self {
|
||||||
let value = cell.get_str_value(CELL_DATA).unwrap_or_default();
|
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 {
|
impl FromStr for SelectOptionIds {
|
||||||
fn from(s: String) -> Self {
|
type Err = FlowyError;
|
||||||
if s.is_empty() {
|
|
||||||
return Self(vec![]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
if s.is_empty() {
|
||||||
|
return Ok(Self(vec![]));
|
||||||
|
}
|
||||||
let ids = s
|
let ids = s
|
||||||
.split(SELECTION_IDS_SEPARATOR)
|
.split(SELECTION_IDS_SEPARATOR)
|
||||||
.map(|id| id.to_string())
|
.map(|id| id.to_string())
|
||||||
.collect::<Vec<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 {
|
fn from(s: Option<String>) -> Self {
|
||||||
match s {
|
match s {
|
||||||
None => Self(vec![]),
|
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
|
&mut self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DecodedCellData for SelectOptionIds {
|
|
||||||
type Object = SelectOptionIds;
|
|
||||||
|
|
||||||
fn is_empty(&self) -> bool {
|
|
||||||
self.0.is_empty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use collab_database::fields::{Field, TypeOptionData};
|
use collab_database::fields::{Field, TypeOptionData};
|
||||||
use collab_database::rows::Cell;
|
use collab_database::rows::Cell;
|
||||||
@ -5,7 +7,7 @@ use collab_database::rows::Cell;
|
|||||||
use flowy_error::{internal_error, ErrorCode, FlowyResult};
|
use flowy_error::{internal_error, ErrorCode, FlowyResult};
|
||||||
|
|
||||||
use crate::entities::{CheckboxCellDataPB, FieldType, SelectOptionCellDataPB};
|
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::selection_type_option::type_option_transform::SelectOptionTypeOptionTransformHelper;
|
||||||
use crate::services::field::{
|
use crate::services::field::{
|
||||||
make_selected_options, MultiSelectTypeOption, SelectOption, SelectOptionCellData,
|
make_selected_options, MultiSelectTypeOption, SelectOption, SelectOptionCellData,
|
||||||
@ -205,20 +207,12 @@ impl CellProtobufBlobParser for SelectOptionIdsParser {
|
|||||||
type Object = SelectOptionIds;
|
type Object = SelectOptionIds;
|
||||||
fn parser(bytes: &Bytes) -> FlowyResult<Self::Object> {
|
fn parser(bytes: &Bytes) -> FlowyResult<Self::Object> {
|
||||||
match String::from_utf8(bytes.to_vec()) {
|
match String::from_utf8(bytes.to_vec()) {
|
||||||
Ok(s) => Ok(SelectOptionIds::from(s)),
|
Ok(s) => SelectOptionIds::from_str(&s),
|
||||||
Err(_) => Ok(SelectOptionIds::from("".to_owned())),
|
Err(_) => Ok(SelectOptionIds::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DecodedCellData for SelectOptionCellDataPB {
|
|
||||||
type Object = SelectOptionCellDataPB;
|
|
||||||
|
|
||||||
fn is_empty(&self) -> bool {
|
|
||||||
self.select_options.is_empty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SelectOptionCellDataParser();
|
pub struct SelectOptionCellDataParser();
|
||||||
impl CellProtobufBlobParser for SelectOptionCellDataParser {
|
impl CellProtobufBlobParser for SelectOptionCellDataParser {
|
||||||
type Object = SelectOptionCellDataPB;
|
type Object = SelectOptionCellDataPB;
|
||||||
|
@ -10,8 +10,7 @@ use flowy_error::{FlowyError, FlowyResult};
|
|||||||
|
|
||||||
use crate::entities::{FieldType, TextFilterPB};
|
use crate::entities::{FieldType, TextFilterPB};
|
||||||
use crate::services::cell::{
|
use crate::services::cell::{
|
||||||
stringify_cell_data, CellDataChangeset, CellDataDecoder, CellProtobufBlobParser, DecodedCellData,
|
stringify_cell_data, CellDataChangeset, CellDataDecoder, CellProtobufBlobParser,
|
||||||
FromCellString,
|
|
||||||
};
|
};
|
||||||
use crate::services::field::type_options::util::ProtobufStr;
|
use crate::services::field::type_options::util::ProtobufStr;
|
||||||
use crate::services::field::{
|
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 {
|
impl ToString for TextCellData {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
self.0.clone()
|
self.0.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DecodedCellData for TextCellData {
|
|
||||||
type Object = TextCellData;
|
|
||||||
|
|
||||||
fn is_empty(&self) -> bool {
|
|
||||||
self.0.is_empty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TextCellDataParser();
|
pub struct TextCellDataParser();
|
||||||
impl CellProtobufBlobParser for TextCellDataParser {
|
impl CellProtobufBlobParser for TextCellDataParser {
|
||||||
type Object = TextCellData;
|
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 {
|
impl std::convert::From<String> for StrCellData {
|
||||||
fn from(s: String) -> Self {
|
fn from(s: String) -> Self {
|
||||||
Self(s)
|
Self(s)
|
||||||
|
@ -23,17 +23,16 @@ use crate::services::filter::FromFilterString;
|
|||||||
use crate::services::sort::SortCondition;
|
use crate::services::sort::SortCondition;
|
||||||
|
|
||||||
pub trait TypeOption {
|
pub trait TypeOption {
|
||||||
/// `CellData` represents as the decoded model for current type option. Each of them impl the
|
/// `CellData` represents the decoded model for the current type option. Each of them must
|
||||||
/// `FromCellString` and `Default` trait. If the cell string can not be decoded into the specified
|
/// implement the From<&Cell> trait. If the `Cell` cannot be decoded into this type, the default
|
||||||
/// cell data type then the default value will be returned.
|
/// value will be returned.
|
||||||
/// For example:
|
///
|
||||||
|
/// Note: Use `StrCellData` for any `TypeOption` whose cell data is simply `String`.
|
||||||
///
|
///
|
||||||
/// - FieldType::Checkbox => CheckboxCellData
|
/// - FieldType::Checkbox => CheckboxCellData
|
||||||
/// - FieldType::Date => DateCellData
|
/// - FieldType::Date => DateCellData
|
||||||
/// - FieldType::URL => URLCellData
|
/// - FieldType::URL => URLCellData
|
||||||
///
|
///
|
||||||
/// Uses `StrCellData` for any `TypeOption` if their cell data is pure `String`.
|
|
||||||
///
|
|
||||||
type CellData: for<'a> From<&'a Cell>
|
type CellData: for<'a> From<&'a Cell>
|
||||||
+ TypeOptionCellData
|
+ TypeOptionCellData
|
||||||
+ ToString
|
+ ToString
|
||||||
|
@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use flowy_error::{internal_error, FlowyResult};
|
use flowy_error::{internal_error, FlowyResult};
|
||||||
|
|
||||||
use crate::entities::{FieldType, URLCellDataPB};
|
use crate::entities::{FieldType, URLCellDataPB};
|
||||||
use crate::services::cell::{CellProtobufBlobParser, DecodedCellData, FromCellString};
|
use crate::services::cell::CellProtobufBlobParser;
|
||||||
use crate::services::field::{TypeOptionCellData, CELL_DATA};
|
use crate::services::field::{TypeOptionCellData, CELL_DATA};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
#[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 {
|
impl From<URLCellDataPB> for URLCellData {
|
||||||
fn from(data: URLCellDataPB) -> Self {
|
fn from(data: URLCellDataPB) -> Self {
|
||||||
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();
|
pub struct URLCellDataParser();
|
||||||
impl CellProtobufBlobParser for URLCellDataParser {
|
impl CellProtobufBlobParser for URLCellDataParser {
|
||||||
type Object = URLCellDataPB;
|
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 {
|
impl ToString for URLCellData {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
self.to_json().unwrap()
|
self.to_json().unwrap()
|
||||||
|
Loading…
Reference in New Issue
Block a user