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_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),
|
||||
|
@ -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));
|
||||
}
|
||||
},
|
||||
|
@ -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>;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user