123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- use crate::impl_from_and_to_type_option;
- use crate::services::row::StringifyCellData;
- use chrono::format::strftime::StrftimeItems;
- use chrono::NaiveDateTime;
- use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
- use flowy_error::FlowyError;
- use flowy_grid_data_model::entities::{Field, FieldType};
- use serde::{Deserialize, Serialize};
- use strum_macros::EnumIter;
- // Date
- #[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)]
- pub struct DateDescription {
- #[pb(index = 1)]
- pub date_format: DateFormat,
- #[pb(index = 2)]
- pub time_format: TimeFormat,
- }
- impl_from_and_to_type_option!(DateDescription, FieldType::DateTime);
- impl DateDescription {
- #[allow(dead_code)]
- fn today_from_timestamp(&self, timestamp: i64) -> String {
- let native = chrono::NaiveDateTime::from_timestamp(timestamp, 0);
- self.today_from_native(native)
- }
- fn today_from_native(&self, naive: chrono::NaiveDateTime) -> String {
- let utc: chrono::DateTime<chrono::Utc> = chrono::DateTime::from_utc(naive, chrono::Utc);
- let local: chrono::DateTime<chrono::Local> = chrono::DateTime::from(utc);
- let fmt_str = format!("{} {}", self.date_format.format_str(), self.time_format.format_str());
- let output = format!("{}", local.format_with_items(StrftimeItems::new(&fmt_str)));
- output
- }
- }
- impl StringifyCellData for DateDescription {
- fn str_from_cell_data(&self, data: String) -> String {
- match data.parse::<i64>() {
- Ok(timestamp) => {
- let native = NaiveDateTime::from_timestamp(timestamp, 0);
- self.today_from_native(native)
- }
- Err(e) => {
- tracing::debug!("DateDescription format {} fail. error: {:?}", data, e);
- String::new()
- }
- }
- }
- fn str_to_cell_data(&self, s: &str) -> Result<String, FlowyError> {
- let timestamp = match s.parse::<i64>() {
- Ok(timestamp) => timestamp,
- Err(e) => {
- tracing::error!("Parse {} to i64 failed: {}", s, e);
- chrono::Utc::now().timestamp()
- }
- };
- Ok(format!("{}", timestamp))
- }
- }
- #[derive(Clone, Debug, Copy, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)]
- pub enum DateFormat {
- Local = 0,
- US = 1,
- ISO = 2,
- Friendly = 3,
- }
- impl std::default::Default for DateFormat {
- fn default() -> Self {
- DateFormat::Friendly
- }
- }
- impl std::convert::From<i32> for DateFormat {
- fn from(value: i32) -> Self {
- match value {
- 0 => DateFormat::Local,
- 1 => DateFormat::US,
- 2 => DateFormat::ISO,
- 3 => DateFormat::Friendly,
- _ => {
- tracing::error!("Unsupported date format, fallback to friendly");
- DateFormat::Friendly
- }
- }
- }
- }
- impl DateFormat {
- pub fn value(&self) -> i32 {
- *self as i32
- }
- // https://docs.rs/chrono/0.4.19/chrono/format/strftime/index.html
- pub fn format_str(&self) -> &'static str {
- match self {
- DateFormat::Local => "%Y/%m/%d",
- DateFormat::US => "%Y/%m/%d",
- DateFormat::ISO => "%Y-%m-%d",
- DateFormat::Friendly => "%b %d,%Y",
- }
- }
- }
- #[derive(Clone, Copy, PartialEq, Eq, EnumIter, Debug, Hash, Serialize, Deserialize, ProtoBuf_Enum)]
- pub enum TimeFormat {
- TwelveHour = 0,
- TwentyFourHour = 1,
- }
- impl std::convert::From<i32> for TimeFormat {
- fn from(value: i32) -> Self {
- match value {
- 0 => TimeFormat::TwelveHour,
- 1 => TimeFormat::TwentyFourHour,
- _ => {
- tracing::error!("Unsupported time format, fallback to TwentyFourHour");
- TimeFormat::TwentyFourHour
- }
- }
- }
- }
- impl TimeFormat {
- pub fn value(&self) -> i32 {
- *self as i32
- }
- // https://docs.rs/chrono/0.4.19/chrono/format/strftime/index.html
- pub fn format_str(&self) -> &'static str {
- match self {
- TimeFormat::TwelveHour => "%r",
- TimeFormat::TwentyFourHour => "%R",
- }
- }
- }
- impl std::default::Default for TimeFormat {
- fn default() -> Self {
- TimeFormat::TwentyFourHour
- }
- }
- #[cfg(test)]
- mod tests {
- use crate::services::cell::{DateDescription, DateFormat, TimeFormat};
- use crate::services::row::StringifyCellData;
- use strum::IntoEnumIterator;
- #[test]
- fn date_description_date_format_test() {
- let mut description = DateDescription::default();
- let _timestamp = 1647251762;
- for date_format in DateFormat::iter() {
- description.date_format = date_format;
- match date_format {
- DateFormat::Friendly => {
- assert_eq!(
- "Mar 14,2022 17:56".to_owned(),
- description.today_from_timestamp(1647251762)
- );
- assert_eq!(
- "Mar 14,2022 17:56".to_owned(),
- description.str_from_cell_data("1647251762".to_owned())
- );
- }
- DateFormat::US => {
- assert_eq!(
- "2022/03/14 17:56".to_owned(),
- description.today_from_timestamp(1647251762)
- );
- assert_eq!(
- "2022/03/14 17:56".to_owned(),
- description.str_from_cell_data("1647251762".to_owned())
- );
- }
- DateFormat::ISO => {
- assert_eq!(
- "2022-03-14 17:56".to_owned(),
- description.today_from_timestamp(1647251762)
- );
- assert_eq!(
- "2022-03-14 17:56".to_owned(),
- description.str_from_cell_data("1647251762".to_owned())
- );
- }
- DateFormat::Local => {
- assert_eq!(
- "2022/03/14 17:56".to_owned(),
- description.today_from_timestamp(1647251762)
- );
- assert_eq!(
- "2022/03/14 17:56".to_owned(),
- description.str_from_cell_data("1647251762".to_owned())
- );
- }
- }
- }
- }
- #[test]
- fn date_description_time_format_test() {
- let mut description = DateDescription::default();
- for time_format in TimeFormat::iter() {
- description.time_format = time_format;
- match time_format {
- TimeFormat::TwentyFourHour => {
- assert_eq!(
- "Mar 14,2022 17:56".to_owned(),
- description.today_from_timestamp(1647251762)
- );
- assert_eq!(
- "Mar 14,2022 17:56".to_owned(),
- description.str_from_cell_data("1647251762".to_owned())
- );
- }
- TimeFormat::TwelveHour => {
- assert_eq!(
- "Mar 14,2022 05:56:02 PM".to_owned(),
- description.today_from_timestamp(1647251762)
- );
- assert_eq!(
- "Mar 14,2022 05:56:02 PM".to_owned(),
- description.str_from_cell_data("1647251762".to_owned())
- );
- }
- }
- }
- }
- #[test]
- fn date_description_invalid_data_test() {
- let description = DateDescription::default();
- description.str_to_cell_data("he").unwrap();
- }
- }
|