Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions collab-database/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ impl Database {

let field_type = FieldType::from(field.field_type);
let type_option = field.get_any_type_option(field_type.type_id())?;
type_option_cell_reader(type_option, &field_type)
Some(type_option_cell_reader(type_option, &field_type))
}

/// Return [TypeOptionCellWriter] for the given field id.
Expand All @@ -518,7 +518,7 @@ impl Database {

let field_type = FieldType::from(field.field_type);
let type_option = field.get_any_type_option(field_type.type_id())?;
type_option_cell_writer(type_option, &field_type)
Some(type_option_cell_writer(type_option, &field_type))
}

#[instrument(level = "debug", skip_all)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl TypeOptionCellReader for CheckboxTypeOption {
}

impl TypeOptionCellWriter for CheckboxTypeOption {
fn write_json(&self, value: Value) -> Cell {
fn convert_json_to_cell(&self, value: Value) -> Cell {
let mut cell = new_cell_builder(FieldType::Checkbox);
if let Some(data) = match value {
Value::String(s) => Some(s),
Expand Down Expand Up @@ -119,17 +119,17 @@ mod tests {

// Write a string
let value = Value::String("true".to_string());
let cell = option.write_json(value);
let cell = option.convert_json_to_cell(value);
assert_eq!(cell.get_as::<String>(CELL_DATA).unwrap(), "true");

// Write a boolean
let value = Value::Bool(true);
let cell = option.write_json(value);
let cell = option.convert_json_to_cell(value);
assert_eq!(cell.get_as::<String>(CELL_DATA).unwrap(), "true");

// Write a number
let value = Value::Number(1.into());
let cell = option.write_json(value);
let cell = option.convert_json_to_cell(value);
assert_eq!(cell.get_as::<String>(CELL_DATA).unwrap(), "true");
}

Expand Down
28 changes: 5 additions & 23 deletions collab-database/src/fields/type_option/checklist_type_option.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use super::{TypeOptionData, TypeOptionDataBuilder};
use crate::entity::FieldType;

use crate::fields::select_type_option::SELECTION_IDS_SEPARATOR;
use crate::fields::{TypeOptionCellReader, TypeOptionCellWriter};
use crate::rows::{new_cell_builder, Cell};
use crate::rows::Cell;
use crate::template::check_list_parse::ChecklistCellData;
use crate::template::entity::CELL_DATA;
use collab::util::AnyMapExt;

use serde::{Deserialize, Serialize};
use serde_json::{json, Value};

Expand Down Expand Up @@ -46,29 +45,12 @@ impl TypeOptionCellReader for ChecklistTypeOption {
}

impl TypeOptionCellWriter for ChecklistTypeOption {
fn write_json(&self, json_value: Value) -> Cell {
fn convert_json_to_cell(&self, json_value: Value) -> Cell {
let cell_data = serde_json::from_value::<ChecklistCellData>(json_value).unwrap_or_default();
cell_data.into()
}
}

impl From<&Cell> for ChecklistCellData {
fn from(cell: &Cell) -> Self {
cell
.get_as::<String>(CELL_DATA)
.map(|data| serde_json::from_str::<ChecklistCellData>(&data).unwrap_or_default())
.unwrap_or_default()
}
}

impl From<ChecklistCellData> for Cell {
fn from(cell_data: ChecklistCellData) -> Self {
let data = serde_json::to_string(&cell_data).unwrap_or_default();
let mut cell = new_cell_builder(FieldType::Checklist);
cell.insert(CELL_DATA.into(), data.into());
cell
}
}
#[cfg(test)]
mod checklist_type_option_tests {
use super::*;
Expand Down Expand Up @@ -132,7 +114,7 @@ mod checklist_type_option_tests {
"selected_option_ids": ["1"]
});

let cell = checklist_option.write_json(json_value);
let cell = checklist_option.convert_json_to_cell(json_value);
let restored_data = ChecklistCellData::from(&cell);

assert_eq!(restored_data.options.len(), 2);
Expand Down
12 changes: 9 additions & 3 deletions collab-database/src/fields/type_option/date_type_option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use serde::{Deserialize, Serialize};
use std::fmt;

use crate::template::time_parse::TimeCellData;
use crate::template::util::TypeOptionCellData;
use serde_json::{json, Value};
use std::str::FromStr;
pub use strum::IntoEnumIterator;
Expand Down Expand Up @@ -41,7 +42,7 @@ impl TypeOptionCellReader for TimeTypeOption {
}

impl TypeOptionCellWriter for TimeTypeOption {
fn write_json(&self, json_value: Value) -> Cell {
fn convert_json_to_cell(&self, json_value: Value) -> Cell {
let cell_data = serde_json::from_value::<TimeCellData>(json_value).unwrap_or_default();
Cell::from(&cell_data)
}
Expand Down Expand Up @@ -117,7 +118,7 @@ impl TypeOptionCellReader for DateTypeOption {
}

impl TypeOptionCellWriter for DateTypeOption {
fn write_json(&self, json_value: Value) -> Cell {
fn convert_json_to_cell(&self, json_value: Value) -> Cell {
let cell_data = serde_json::from_value::<DateCellData>(json_value).unwrap();
Cell::from(&cell_data)
}
Expand Down Expand Up @@ -351,6 +352,11 @@ pub struct DateCellData {
pub is_range: bool,
pub reminder_id: String,
}
impl TypeOptionCellData for DateCellData {
fn is_empty(&self) -> bool {
self.timestamp.is_none()
}
}

impl DateCellData {
pub fn new(timestamp: i64, include_time: bool, is_range: bool, reminder_id: String) -> Self {
Expand Down Expand Up @@ -629,7 +635,7 @@ mod tests {
"reminder_id": "reminder123"
});

let cell = date_type_option.write_json(json_value);
let cell = date_type_option.convert_json_to_cell(json_value);
assert_eq!(
cell.get_as::<String>(CELL_DATA),
Some("1672531200".to_string())
Expand Down
10 changes: 9 additions & 1 deletion collab-database/src/fields/type_option/media_type_option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ use crate::fields::{
TypeOptionCellReader, TypeOptionCellWriter, TypeOptionData, TypeOptionDataBuilder,
};
use crate::rows::{new_cell_builder, Cell};

use crate::template::entity::CELL_DATA;
use crate::template::util::TypeOptionCellData;
use collab::util::AnyMapExt;
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::{json, Value};
Expand Down Expand Up @@ -52,7 +54,7 @@ impl TypeOptionCellReader for MediaTypeOption {
}

impl TypeOptionCellWriter for MediaTypeOption {
fn write_json(&self, json_value: Value) -> Cell {
fn convert_json_to_cell(&self, json_value: Value) -> Cell {
let cell_data = serde_json::from_value::<MediaCellData>(json_value).unwrap_or_default();
cell_data.into()
}
Expand All @@ -79,6 +81,12 @@ pub struct MediaCellData {
pub files: Vec<MediaFile>,
}

impl TypeOptionCellData for MediaCellData {
fn is_empty(&self) -> bool {
self.files.is_empty()
}
}

impl From<MediaCellData> for Any {
fn from(data: MediaCellData) -> Self {
Any::Array(Arc::from(
Expand Down
69 changes: 34 additions & 35 deletions collab-database/src/fields/type_option/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,54 +152,53 @@ pub trait TypeOptionCellReader {
/// [TypeOptionCellWriter] is a trait that provides methods to write [serde_json::Value] into a cell.
/// Different field types have their own implementation about how to convert [serde_json::Value] into [Cell].
pub trait TypeOptionCellWriter {
/// Write json value into a cell
/// Convert json value into a cell
/// Different type option has its own implementation about how to convert [serde_json::Value]
/// into [Cell]
fn write_json(&self, json_value: serde_json::Value) -> Cell;
fn convert_json_to_cell(&self, json_value: serde_json::Value) -> Cell;
}

pub fn type_option_cell_writer(
type_option_data: TypeOptionData,
field_type: &FieldType,
) -> Option<Box<dyn TypeOptionCellWriter>> {
) -> Box<dyn TypeOptionCellWriter> {
match field_type {
FieldType::RichText => Some(Box::new(RichTextTypeOption::from(type_option_data))),
FieldType::Number => Some(Box::new(NumberTypeOption::from(type_option_data))),
FieldType::DateTime => Some(Box::new(DateTypeOption::from(type_option_data))),
FieldType::SingleSelect => Some(Box::new(SingleSelectTypeOption::from(type_option_data))),
FieldType::MultiSelect => Some(Box::new(MultiSelectTypeOption::from(type_option_data))),
FieldType::Checkbox => Some(Box::new(CheckboxTypeOption::from(type_option_data))),
FieldType::URL => Some(Box::new(URLTypeOption::from(type_option_data))),
FieldType::Time => Some(Box::new(TimeTypeOption::from(type_option_data))),
FieldType::Media => Some(Box::new(MediaTypeOption::from(type_option_data))),
FieldType::Checklist => Some(Box::new(ChecklistTypeOption::from(type_option_data))),
FieldType::LastEditedTime => Some(Box::new(TimestampTypeOption::from(type_option_data))),
FieldType::CreatedTime => Some(Box::new(TimestampTypeOption::from(type_option_data))),
FieldType::Relation => Some(Box::new(RelationTypeOption::from(type_option_data))),
FieldType::Summary => Some(Box::new(SummarizationTypeOption::from(type_option_data))),
FieldType::Translate => Some(Box::new(TranslateTypeOption::from(type_option_data))),
FieldType::RichText => Box::new(RichTextTypeOption::from(type_option_data)),
FieldType::Number => Box::new(NumberTypeOption::from(type_option_data)),
FieldType::DateTime => Box::new(DateTypeOption::from(type_option_data)),
FieldType::SingleSelect => Box::new(SingleSelectTypeOption::from(type_option_data)),
FieldType::MultiSelect => Box::new(MultiSelectTypeOption::from(type_option_data)),
FieldType::Checkbox => Box::new(CheckboxTypeOption::from(type_option_data)),
FieldType::URL => Box::new(URLTypeOption::from(type_option_data)),
FieldType::Time => Box::new(TimeTypeOption::from(type_option_data)),
FieldType::Media => Box::new(MediaTypeOption::from(type_option_data)),
FieldType::Checklist => Box::new(ChecklistTypeOption::from(type_option_data)),
FieldType::LastEditedTime => Box::new(TimestampTypeOption::from(type_option_data)),
FieldType::CreatedTime => Box::new(TimestampTypeOption::from(type_option_data)),
FieldType::Relation => Box::new(RelationTypeOption::from(type_option_data)),
FieldType::Summary => Box::new(SummarizationTypeOption::from(type_option_data)),
FieldType::Translate => Box::new(TranslateTypeOption::from(type_option_data)),
}
}

pub fn type_option_cell_reader(
type_option_data: TypeOptionData,
field_type: &FieldType,
) -> Option<Box<dyn TypeOptionCellReader>> {
) -> Box<dyn TypeOptionCellReader> {
match field_type {
FieldType::RichText => Some(Box::new(RichTextTypeOption::from(type_option_data))),
FieldType::Number => Some(Box::new(NumberTypeOption::from(type_option_data))),
FieldType::DateTime => Some(Box::new(DateTypeOption::from(type_option_data))),
FieldType::SingleSelect => Some(Box::new(SingleSelectTypeOption::from(type_option_data))),
FieldType::MultiSelect => Some(Box::new(MultiSelectTypeOption::from(type_option_data))),
FieldType::Checkbox => Some(Box::new(CheckboxTypeOption::from(type_option_data))),
FieldType::URL => Some(Box::new(URLTypeOption::from(type_option_data))),
FieldType::Time => Some(Box::new(TimeTypeOption::from(type_option_data))),
FieldType::Media => Some(Box::new(MediaTypeOption::from(type_option_data))),
FieldType::Checklist => Some(Box::new(ChecklistTypeOption::from(type_option_data))),
FieldType::LastEditedTime => Some(Box::new(TimestampTypeOption::from(type_option_data))),
FieldType::CreatedTime => Some(Box::new(TimestampTypeOption::from(type_option_data))),
FieldType::Relation => Some(Box::new(RelationTypeOption::from(type_option_data))),
FieldType::Summary => Some(Box::new(SummarizationTypeOption::from(type_option_data))),
FieldType::Translate => Some(Box::new(TranslateTypeOption::from(type_option_data))),
FieldType::RichText => Box::new(RichTextTypeOption::from(type_option_data)),
FieldType::Number => Box::new(NumberTypeOption::from(type_option_data)),
FieldType::DateTime => Box::new(DateTypeOption::from(type_option_data)),
FieldType::SingleSelect => Box::new(SingleSelectTypeOption::from(type_option_data)),
FieldType::MultiSelect => Box::new(MultiSelectTypeOption::from(type_option_data)),
FieldType::Checkbox => Box::new(CheckboxTypeOption::from(type_option_data)),
FieldType::URL => Box::new(URLTypeOption::from(type_option_data)),
FieldType::Time => Box::new(TimeTypeOption::from(type_option_data)),
FieldType::Media => Box::new(MediaTypeOption::from(type_option_data)),
FieldType::Checklist => Box::new(ChecklistTypeOption::from(type_option_data)),
FieldType::LastEditedTime => Box::new(TimestampTypeOption::from(type_option_data)),
FieldType::CreatedTime => Box::new(TimestampTypeOption::from(type_option_data)),
FieldType::Relation => Box::new(RelationTypeOption::from(type_option_data)),
FieldType::Summary => Box::new(SummarizationTypeOption::from(type_option_data)),
FieldType::Translate => Box::new(TranslateTypeOption::from(type_option_data)),
}
}
16 changes: 8 additions & 8 deletions collab-database/src/fields/type_option/number_type_option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use collab::preclude::Any;

use crate::entity::FieldType;
use crate::rows::{new_cell_builder, Cell};
use crate::template::entity::CELL_DATA;
use collab::util::AnyMapExt;
use crate::template::number_parse::NumberCellData;

use fancy_regex::Regex;
use lazy_static::lazy_static;
use rust_decimal::Decimal;
Expand Down Expand Up @@ -72,8 +72,8 @@ impl TypeOptionCellReader for NumberTypeOption {
}

fn numeric_cell(&self, cell: &Cell) -> Option<f64> {
let cell_data = cell.get_as::<String>(CELL_DATA)?;
cell_data.parse::<f64>().ok()
let cell_data = NumberCellData::from(cell);
cell_data.0.parse::<f64>().ok()
}

fn convert_raw_cell_data(&self, text: &str) -> String {
Expand All @@ -85,16 +85,16 @@ impl TypeOptionCellReader for NumberTypeOption {
}

impl TypeOptionCellWriter for NumberTypeOption {
fn write_json(&self, json_value: Value) -> Cell {
let mut cell = new_cell_builder(FieldType::Number);
fn convert_json_to_cell(&self, json_value: Value) -> Cell {
if let Some(data) = match json_value {
Value::String(s) => Some(s),
Value::Number(n) => Some(n.to_string()),
_ => None,
} {
cell.insert(CELL_DATA.into(), data.into());
NumberCellData(data).into()
} else {
new_cell_builder(FieldType::Number)
}
cell
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ impl TypeOptionCellReader for RelationTypeOption {
}

impl TypeOptionCellWriter for RelationTypeOption {
fn write_json(&self, json_value: Value) -> Cell {
fn convert_json_to_cell(&self, json_value: Value) -> Cell {
let cell_data = serde_json::from_value::<RelationCellData>(json_value).unwrap_or_default();
Cell::from(&cell_data)
Cell::from(cell_data)
}
}
16 changes: 12 additions & 4 deletions collab-database/src/fields/type_option/select_type_option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use crate::fields::{
};
use crate::rows::{new_cell_builder, Cell};
use crate::template::entity::CELL_DATA;

use crate::template::util::TypeOptionCellData;
use collab::util::AnyMapExt;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
Expand Down Expand Up @@ -194,7 +196,7 @@ impl TypeOptionCellReader for SingleSelectTypeOption {
}

impl TypeOptionCellWriter for SingleSelectTypeOption {
fn write_json(&self, value: Value) -> Cell {
fn convert_json_to_cell(&self, value: Value) -> Cell {
cell_from_json_value(value, &self.options, FieldType::SingleSelect)
}
}
Expand Down Expand Up @@ -243,7 +245,7 @@ impl TypeOptionCellReader for MultiSelectTypeOption {
}

impl TypeOptionCellWriter for MultiSelectTypeOption {
fn write_json(&self, value: Value) -> Cell {
fn convert_json_to_cell(&self, value: Value) -> Cell {
cell_from_json_value(value, &self.options, FieldType::MultiSelect)
}
}
Expand Down Expand Up @@ -290,6 +292,12 @@ impl SelectOptionIds {
}
}

impl TypeOptionCellData for SelectOptionIds {
fn is_empty(&self) -> bool {
self.0.is_empty()
}
}

pub const SELECTION_IDS_SEPARATOR: &str = ",";

impl std::convert::From<Vec<String>> for SelectOptionIds {
Expand Down Expand Up @@ -483,7 +491,7 @@ mod tests {
});

let json_value = json!({ "name": "Option A" });
let cell = single_select.write_json(json_value);
let cell = single_select.convert_json_to_cell(json_value);

let cell_data: String = cell.get_as(CELL_DATA).unwrap();
assert!(!cell_data.is_empty());
Expand All @@ -502,7 +510,7 @@ mod tests {
{ "id": multi_select.options[1].id }
]);

let cell = multi_select.write_json(json_value);
let cell = multi_select.convert_json_to_cell(json_value);
let cell_data: String = cell.get_as(CELL_DATA).unwrap();
assert!(cell_data.contains(&multi_select.options[0].id));
assert!(cell_data.contains(&multi_select.options[1].id));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl TypeOptionCellReader for SummarizationTypeOption {
}

impl TypeOptionCellWriter for SummarizationTypeOption {
fn write_json(&self, json_value: Value) -> Cell {
fn convert_json_to_cell(&self, json_value: Value) -> Cell {
let cell_data = serde_json::from_value::<SummaryCellData>(json_value).unwrap_or_default();
cell_data.into()
}
Expand Down
Loading
Loading