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_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),

View File

@ -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));
} }
}, },

View File

@ -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>;
} }

View File

@ -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
) )

View File

@ -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;

View File

@ -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;

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::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;

View File

@ -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");

View File

@ -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()
}
}

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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()