Skip to content

Commit cc31b09

Browse files
authored
Fix timestamp typeoption (#340)
* chore: update timestamp type option * chore: imple type option cell * chore: rename * chore: remove option * chore: debug * chore: to string * chore: update
1 parent 6cdf924 commit cc31b09

24 files changed

+278
-98
lines changed

collab-database/src/database.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ impl Database {
507507

508508
let field_type = FieldType::from(field.field_type);
509509
let type_option = field.get_any_type_option(field_type.type_id())?;
510-
type_option_cell_reader(type_option, &field_type)
510+
Some(type_option_cell_reader(type_option, &field_type))
511511
}
512512

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

519519
let field_type = FieldType::from(field.field_type);
520520
let type_option = field.get_any_type_option(field_type.type_id())?;
521-
type_option_cell_writer(type_option, &field_type)
521+
Some(type_option_cell_writer(type_option, &field_type))
522522
}
523523

524524
#[instrument(level = "debug", skip_all)]

collab-database/src/fields/type_option/checkbox_type_option.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl TypeOptionCellReader for CheckboxTypeOption {
4141
}
4242

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

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

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

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

collab-database/src/fields/type_option/checklist_type_option.rs

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use super::{TypeOptionData, TypeOptionDataBuilder};
2-
use crate::entity::FieldType;
2+
33
use crate::fields::select_type_option::SELECTION_IDS_SEPARATOR;
44
use crate::fields::{TypeOptionCellReader, TypeOptionCellWriter};
5-
use crate::rows::{new_cell_builder, Cell};
5+
use crate::rows::Cell;
66
use crate::template::check_list_parse::ChecklistCellData;
7-
use crate::template::entity::CELL_DATA;
8-
use collab::util::AnyMapExt;
7+
98
use serde::{Deserialize, Serialize};
109
use serde_json::{json, Value};
1110

@@ -46,29 +45,12 @@ impl TypeOptionCellReader for ChecklistTypeOption {
4645
}
4746

4847
impl TypeOptionCellWriter for ChecklistTypeOption {
49-
fn write_json(&self, json_value: Value) -> Cell {
48+
fn convert_json_to_cell(&self, json_value: Value) -> Cell {
5049
let cell_data = serde_json::from_value::<ChecklistCellData>(json_value).unwrap_or_default();
5150
cell_data.into()
5251
}
5352
}
5453

55-
impl From<&Cell> for ChecklistCellData {
56-
fn from(cell: &Cell) -> Self {
57-
cell
58-
.get_as::<String>(CELL_DATA)
59-
.map(|data| serde_json::from_str::<ChecklistCellData>(&data).unwrap_or_default())
60-
.unwrap_or_default()
61-
}
62-
}
63-
64-
impl From<ChecklistCellData> for Cell {
65-
fn from(cell_data: ChecklistCellData) -> Self {
66-
let data = serde_json::to_string(&cell_data).unwrap_or_default();
67-
let mut cell = new_cell_builder(FieldType::Checklist);
68-
cell.insert(CELL_DATA.into(), data.into());
69-
cell
70-
}
71-
}
7254
#[cfg(test)]
7355
mod checklist_type_option_tests {
7456
use super::*;
@@ -132,7 +114,7 @@ mod checklist_type_option_tests {
132114
"selected_option_ids": ["1"]
133115
});
134116

135-
let cell = checklist_option.write_json(json_value);
117+
let cell = checklist_option.convert_json_to_cell(json_value);
136118
let restored_data = ChecklistCellData::from(&cell);
137119

138120
assert_eq!(restored_data.options.len(), 2);

collab-database/src/fields/type_option/date_type_option.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use serde::{Deserialize, Serialize};
1414
use std::fmt;
1515

1616
use crate::template::time_parse::TimeCellData;
17+
use crate::template::util::TypeOptionCellData;
1718
use serde_json::{json, Value};
1819
use std::str::FromStr;
1920
pub use strum::IntoEnumIterator;
@@ -41,7 +42,7 @@ impl TypeOptionCellReader for TimeTypeOption {
4142
}
4243

4344
impl TypeOptionCellWriter for TimeTypeOption {
44-
fn write_json(&self, json_value: Value) -> Cell {
45+
fn convert_json_to_cell(&self, json_value: Value) -> Cell {
4546
let cell_data = serde_json::from_value::<TimeCellData>(json_value).unwrap_or_default();
4647
Cell::from(&cell_data)
4748
}
@@ -117,7 +118,7 @@ impl TypeOptionCellReader for DateTypeOption {
117118
}
118119

119120
impl TypeOptionCellWriter for DateTypeOption {
120-
fn write_json(&self, json_value: Value) -> Cell {
121+
fn convert_json_to_cell(&self, json_value: Value) -> Cell {
121122
let cell_data = serde_json::from_value::<DateCellData>(json_value).unwrap();
122123
Cell::from(&cell_data)
123124
}
@@ -351,6 +352,11 @@ pub struct DateCellData {
351352
pub is_range: bool,
352353
pub reminder_id: String,
353354
}
355+
impl TypeOptionCellData for DateCellData {
356+
fn is_empty(&self) -> bool {
357+
self.timestamp.is_none()
358+
}
359+
}
354360

355361
impl DateCellData {
356362
pub fn new(timestamp: i64, include_time: bool, is_range: bool, reminder_id: String) -> Self {
@@ -629,7 +635,7 @@ mod tests {
629635
"reminder_id": "reminder123"
630636
});
631637

632-
let cell = date_type_option.write_json(json_value);
638+
let cell = date_type_option.convert_json_to_cell(json_value);
633639
assert_eq!(
634640
cell.get_as::<String>(CELL_DATA),
635641
Some("1672531200".to_string())

collab-database/src/fields/type_option/media_type_option.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use crate::fields::{
44
TypeOptionCellReader, TypeOptionCellWriter, TypeOptionData, TypeOptionDataBuilder,
55
};
66
use crate::rows::{new_cell_builder, Cell};
7+
78
use crate::template::entity::CELL_DATA;
9+
use crate::template::util::TypeOptionCellData;
810
use collab::util::AnyMapExt;
911
use serde::{Deserialize, Deserializer, Serialize};
1012
use serde_json::{json, Value};
@@ -52,7 +54,7 @@ impl TypeOptionCellReader for MediaTypeOption {
5254
}
5355

5456
impl TypeOptionCellWriter for MediaTypeOption {
55-
fn write_json(&self, json_value: Value) -> Cell {
57+
fn convert_json_to_cell(&self, json_value: Value) -> Cell {
5658
let cell_data = serde_json::from_value::<MediaCellData>(json_value).unwrap_or_default();
5759
cell_data.into()
5860
}
@@ -79,6 +81,12 @@ pub struct MediaCellData {
7981
pub files: Vec<MediaFile>,
8082
}
8183

84+
impl TypeOptionCellData for MediaCellData {
85+
fn is_empty(&self) -> bool {
86+
self.files.is_empty()
87+
}
88+
}
89+
8290
impl From<MediaCellData> for Any {
8391
fn from(data: MediaCellData) -> Self {
8492
Any::Array(Arc::from(

collab-database/src/fields/type_option/mod.rs

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -152,54 +152,53 @@ pub trait TypeOptionCellReader {
152152
/// [TypeOptionCellWriter] is a trait that provides methods to write [serde_json::Value] into a cell.
153153
/// Different field types have their own implementation about how to convert [serde_json::Value] into [Cell].
154154
pub trait TypeOptionCellWriter {
155-
/// Write json value into a cell
155+
/// Convert json value into a cell
156156
/// Different type option has its own implementation about how to convert [serde_json::Value]
157157
/// into [Cell]
158-
fn write_json(&self, json_value: serde_json::Value) -> Cell;
158+
fn convert_json_to_cell(&self, json_value: serde_json::Value) -> Cell;
159159
}
160-
161160
pub fn type_option_cell_writer(
162161
type_option_data: TypeOptionData,
163162
field_type: &FieldType,
164-
) -> Option<Box<dyn TypeOptionCellWriter>> {
163+
) -> Box<dyn TypeOptionCellWriter> {
165164
match field_type {
166-
FieldType::RichText => Some(Box::new(RichTextTypeOption::from(type_option_data))),
167-
FieldType::Number => Some(Box::new(NumberTypeOption::from(type_option_data))),
168-
FieldType::DateTime => Some(Box::new(DateTypeOption::from(type_option_data))),
169-
FieldType::SingleSelect => Some(Box::new(SingleSelectTypeOption::from(type_option_data))),
170-
FieldType::MultiSelect => Some(Box::new(MultiSelectTypeOption::from(type_option_data))),
171-
FieldType::Checkbox => Some(Box::new(CheckboxTypeOption::from(type_option_data))),
172-
FieldType::URL => Some(Box::new(URLTypeOption::from(type_option_data))),
173-
FieldType::Time => Some(Box::new(TimeTypeOption::from(type_option_data))),
174-
FieldType::Media => Some(Box::new(MediaTypeOption::from(type_option_data))),
175-
FieldType::Checklist => Some(Box::new(ChecklistTypeOption::from(type_option_data))),
176-
FieldType::LastEditedTime => Some(Box::new(TimestampTypeOption::from(type_option_data))),
177-
FieldType::CreatedTime => Some(Box::new(TimestampTypeOption::from(type_option_data))),
178-
FieldType::Relation => Some(Box::new(RelationTypeOption::from(type_option_data))),
179-
FieldType::Summary => Some(Box::new(SummarizationTypeOption::from(type_option_data))),
180-
FieldType::Translate => Some(Box::new(TranslateTypeOption::from(type_option_data))),
165+
FieldType::RichText => Box::new(RichTextTypeOption::from(type_option_data)),
166+
FieldType::Number => Box::new(NumberTypeOption::from(type_option_data)),
167+
FieldType::DateTime => Box::new(DateTypeOption::from(type_option_data)),
168+
FieldType::SingleSelect => Box::new(SingleSelectTypeOption::from(type_option_data)),
169+
FieldType::MultiSelect => Box::new(MultiSelectTypeOption::from(type_option_data)),
170+
FieldType::Checkbox => Box::new(CheckboxTypeOption::from(type_option_data)),
171+
FieldType::URL => Box::new(URLTypeOption::from(type_option_data)),
172+
FieldType::Time => Box::new(TimeTypeOption::from(type_option_data)),
173+
FieldType::Media => Box::new(MediaTypeOption::from(type_option_data)),
174+
FieldType::Checklist => Box::new(ChecklistTypeOption::from(type_option_data)),
175+
FieldType::LastEditedTime => Box::new(TimestampTypeOption::from(type_option_data)),
176+
FieldType::CreatedTime => Box::new(TimestampTypeOption::from(type_option_data)),
177+
FieldType::Relation => Box::new(RelationTypeOption::from(type_option_data)),
178+
FieldType::Summary => Box::new(SummarizationTypeOption::from(type_option_data)),
179+
FieldType::Translate => Box::new(TranslateTypeOption::from(type_option_data)),
181180
}
182181
}
183182

184183
pub fn type_option_cell_reader(
185184
type_option_data: TypeOptionData,
186185
field_type: &FieldType,
187-
) -> Option<Box<dyn TypeOptionCellReader>> {
186+
) -> Box<dyn TypeOptionCellReader> {
188187
match field_type {
189-
FieldType::RichText => Some(Box::new(RichTextTypeOption::from(type_option_data))),
190-
FieldType::Number => Some(Box::new(NumberTypeOption::from(type_option_data))),
191-
FieldType::DateTime => Some(Box::new(DateTypeOption::from(type_option_data))),
192-
FieldType::SingleSelect => Some(Box::new(SingleSelectTypeOption::from(type_option_data))),
193-
FieldType::MultiSelect => Some(Box::new(MultiSelectTypeOption::from(type_option_data))),
194-
FieldType::Checkbox => Some(Box::new(CheckboxTypeOption::from(type_option_data))),
195-
FieldType::URL => Some(Box::new(URLTypeOption::from(type_option_data))),
196-
FieldType::Time => Some(Box::new(TimeTypeOption::from(type_option_data))),
197-
FieldType::Media => Some(Box::new(MediaTypeOption::from(type_option_data))),
198-
FieldType::Checklist => Some(Box::new(ChecklistTypeOption::from(type_option_data))),
199-
FieldType::LastEditedTime => Some(Box::new(TimestampTypeOption::from(type_option_data))),
200-
FieldType::CreatedTime => Some(Box::new(TimestampTypeOption::from(type_option_data))),
201-
FieldType::Relation => Some(Box::new(RelationTypeOption::from(type_option_data))),
202-
FieldType::Summary => Some(Box::new(SummarizationTypeOption::from(type_option_data))),
203-
FieldType::Translate => Some(Box::new(TranslateTypeOption::from(type_option_data))),
188+
FieldType::RichText => Box::new(RichTextTypeOption::from(type_option_data)),
189+
FieldType::Number => Box::new(NumberTypeOption::from(type_option_data)),
190+
FieldType::DateTime => Box::new(DateTypeOption::from(type_option_data)),
191+
FieldType::SingleSelect => Box::new(SingleSelectTypeOption::from(type_option_data)),
192+
FieldType::MultiSelect => Box::new(MultiSelectTypeOption::from(type_option_data)),
193+
FieldType::Checkbox => Box::new(CheckboxTypeOption::from(type_option_data)),
194+
FieldType::URL => Box::new(URLTypeOption::from(type_option_data)),
195+
FieldType::Time => Box::new(TimeTypeOption::from(type_option_data)),
196+
FieldType::Media => Box::new(MediaTypeOption::from(type_option_data)),
197+
FieldType::Checklist => Box::new(ChecklistTypeOption::from(type_option_data)),
198+
FieldType::LastEditedTime => Box::new(TimestampTypeOption::from(type_option_data)),
199+
FieldType::CreatedTime => Box::new(TimestampTypeOption::from(type_option_data)),
200+
FieldType::Relation => Box::new(RelationTypeOption::from(type_option_data)),
201+
FieldType::Summary => Box::new(SummarizationTypeOption::from(type_option_data)),
202+
FieldType::Translate => Box::new(TranslateTypeOption::from(type_option_data)),
204203
}
205204
}

collab-database/src/fields/type_option/number_type_option.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use collab::preclude::Any;
1010

1111
use crate::entity::FieldType;
1212
use crate::rows::{new_cell_builder, Cell};
13-
use crate::template::entity::CELL_DATA;
14-
use collab::util::AnyMapExt;
13+
use crate::template::number_parse::NumberCellData;
14+
1515
use fancy_regex::Regex;
1616
use lazy_static::lazy_static;
1717
use rust_decimal::Decimal;
@@ -72,8 +72,8 @@ impl TypeOptionCellReader for NumberTypeOption {
7272
}
7373

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

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

8787
impl TypeOptionCellWriter for NumberTypeOption {
88-
fn write_json(&self, json_value: Value) -> Cell {
89-
let mut cell = new_cell_builder(FieldType::Number);
88+
fn convert_json_to_cell(&self, json_value: Value) -> Cell {
9089
if let Some(data) = match json_value {
9190
Value::String(s) => Some(s),
9291
Value::Number(n) => Some(n.to_string()),
9392
_ => None,
9493
} {
95-
cell.insert(CELL_DATA.into(), data.into());
94+
NumberCellData(data).into()
95+
} else {
96+
new_cell_builder(FieldType::Number)
9697
}
97-
cell
9898
}
9999
}
100100

collab-database/src/fields/type_option/relation_type_option.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ impl TypeOptionCellReader for RelationTypeOption {
4646
}
4747

4848
impl TypeOptionCellWriter for RelationTypeOption {
49-
fn write_json(&self, json_value: Value) -> Cell {
49+
fn convert_json_to_cell(&self, json_value: Value) -> Cell {
5050
let cell_data = serde_json::from_value::<RelationCellData>(json_value).unwrap_or_default();
51-
Cell::from(&cell_data)
51+
Cell::from(cell_data)
5252
}
5353
}

collab-database/src/fields/type_option/select_type_option.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use crate::fields::{
77
};
88
use crate::rows::{new_cell_builder, Cell};
99
use crate::template::entity::CELL_DATA;
10+
11+
use crate::template::util::TypeOptionCellData;
1012
use collab::util::AnyMapExt;
1113
use serde::{Deserialize, Serialize};
1214
use serde_json::{json, Value};
@@ -194,7 +196,7 @@ impl TypeOptionCellReader for SingleSelectTypeOption {
194196
}
195197

196198
impl TypeOptionCellWriter for SingleSelectTypeOption {
197-
fn write_json(&self, value: Value) -> Cell {
199+
fn convert_json_to_cell(&self, value: Value) -> Cell {
198200
cell_from_json_value(value, &self.options, FieldType::SingleSelect)
199201
}
200202
}
@@ -243,7 +245,7 @@ impl TypeOptionCellReader for MultiSelectTypeOption {
243245
}
244246

245247
impl TypeOptionCellWriter for MultiSelectTypeOption {
246-
fn write_json(&self, value: Value) -> Cell {
248+
fn convert_json_to_cell(&self, value: Value) -> Cell {
247249
cell_from_json_value(value, &self.options, FieldType::MultiSelect)
248250
}
249251
}
@@ -290,6 +292,12 @@ impl SelectOptionIds {
290292
}
291293
}
292294

295+
impl TypeOptionCellData for SelectOptionIds {
296+
fn is_empty(&self) -> bool {
297+
self.0.is_empty()
298+
}
299+
}
300+
293301
pub const SELECTION_IDS_SEPARATOR: &str = ",";
294302

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

485493
let json_value = json!({ "name": "Option A" });
486-
let cell = single_select.write_json(json_value);
494+
let cell = single_select.convert_json_to_cell(json_value);
487495

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

505-
let cell = multi_select.write_json(json_value);
513+
let cell = multi_select.convert_json_to_cell(json_value);
506514
let cell_data: String = cell.get_as(CELL_DATA).unwrap();
507515
assert!(cell_data.contains(&multi_select.options[0].id));
508516
assert!(cell_data.contains(&multi_select.options[1].id));

collab-database/src/fields/type_option/summary_type_option.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl TypeOptionCellReader for SummarizationTypeOption {
4141
}
4242

4343
impl TypeOptionCellWriter for SummarizationTypeOption {
44-
fn write_json(&self, json_value: Value) -> Cell {
44+
fn convert_json_to_cell(&self, json_value: Value) -> Cell {
4545
let cell_data = serde_json::from_value::<SummaryCellData>(json_value).unwrap_or_default();
4646
cell_data.into()
4747
}

0 commit comments

Comments
 (0)