From 8bc7af0d3f32e24996ba90b4c53bf815e0e27b5f Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 24 Jul 2022 17:12:22 +0200 Subject: [PATCH] Replace chrono dependency by time --- Cargo.lock | 63 +++++++++++++++----------------------- Cargo.toml | 7 +++-- src/euph/api/types.rs | 10 ++---- src/euph/room.rs | 10 +++--- src/export.rs | 11 +++++-- src/logger.rs | 8 ++--- src/store.rs | 4 +-- src/ui/chat/tree/blocks.rs | 8 ++--- src/ui/chat/tree/render.rs | 10 +++--- src/ui/chat/tree/util.rs | 5 ++- src/vault/euph.rs | 16 +++++----- 11 files changed, 76 insertions(+), 76 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a21cd87..be43956 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -116,20 +116,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "serde", - "time", - "winapi", -] - [[package]] name = "clap" version = "3.2.12" @@ -191,7 +177,6 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", - "chrono", "clap", "crossterm", "directories", @@ -205,6 +190,7 @@ dependencies = [ "serde", "serde_json", "thiserror", + "time", "tokio", "tokio-tungstenite", "toss", @@ -455,7 +441,7 @@ checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -615,20 +601,10 @@ checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys", ] -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.15" @@ -648,6 +624,15 @@ dependencies = [ "libc", ] +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + [[package]] name = "once_cell" version = "1.13.0" @@ -882,12 +867,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" dependencies = [ "bitflags", - "chrono", "fallible-iterator", "fallible-streaming-iterator", "hashlink", "libsqlite3-sys", "smallvec", + "time", ] [[package]] @@ -1146,15 +1131,23 @@ dependencies = [ [[package]] name = "time" -version = "0.1.44" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217" dependencies = [ + "itoa", "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", + "num_threads", + "serde", + "time-macros", ] +[[package]] +name = "time-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" + [[package]] name = "tinyvec" version = "1.6.0" @@ -1354,12 +1347,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index 92c0b7e..91a7b28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,6 @@ edition = "2021" [dependencies] anyhow = "1.0.58" async-trait = "0.1.56" -chrono = { version = "0.4.19", features = ["serde"] } clap = { version = "3.2.12", features = ["derive"] } crossterm = "0.24.0" directories = "4.0.1" @@ -16,7 +15,7 @@ log = { version = "0.4.17", features = ["std"] } palette = { version = "0.6.0", default-features = false, features = ["std"] } parking_lot = "0.12.1" rand = "0.8.5" -rusqlite = { version = "0.28.0", features = ["bundled", "chrono"] } +rusqlite = { version = "0.28.0", features = ["bundled", "time"] } serde = { version = "1.0.139", features = ["derive"] } serde_json = "1.0.82" thiserror = "1.0.31" @@ -24,6 +23,10 @@ tokio = { version = "1.20.0", features = ["full"] } unicode-segmentation = "1.9.0" unicode-width = "0.1.9" +[dependencies.time] +version = "0.3.11" +features = ["macros", "formatting", "parsing", "serde"] + [dependencies.tokio-tungstenite] version = "0.17.2" features = ["rustls-tls-native-roots"] diff --git a/src/euph/api/types.rs b/src/euph/api/types.rs index adb7772..1f77811 100644 --- a/src/euph/api/types.rs +++ b/src/euph/api/types.rs @@ -8,9 +8,9 @@ use std::fmt; -use chrono::{DateTime, TimeZone, Utc}; use serde::{de, ser, Deserialize, Serialize}; use serde_json::Value; +use time::OffsetDateTime; /// Describes an account and its preferred name. #[derive(Debug, Clone, Serialize, Deserialize)] @@ -331,15 +331,11 @@ impl<'de> Deserialize<'de> for Snowflake { /// Time is specified as a signed 64-bit integer, giving the number of seconds /// since the Unix Epoch. #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] -pub struct Time(#[serde(with = "chrono::serde::ts_seconds")] pub DateTime); +pub struct Time(#[serde(with = "time::serde::timestamp")] pub OffsetDateTime); impl Time { - pub fn new(timestamp: i64) -> Self { - Self(Utc.timestamp(timestamp, 0)) - } - pub fn now() -> Self { - Self::new(Utc::now().timestamp()) + Self(OffsetDateTime::now_utc().replace_millisecond(0).unwrap()) } } diff --git a/src/euph/room.rs b/src/euph/room.rs index 86de46d..a9ac101 100644 --- a/src/euph/room.rs +++ b/src/euph/room.rs @@ -3,11 +3,11 @@ use std::sync::Arc; use std::time::Duration; use anyhow::bail; -use chrono::Utc; use log::{error, info, warn}; use parking_lot::Mutex; +use time::OffsetDateTime; use tokio::sync::{mpsc, oneshot}; -use tokio::{select, task, time}; +use tokio::{select, task}; use tokio_tungstenite::tungstenite; use crate::ui::UiEvent; @@ -82,7 +82,7 @@ impl State { } else { info!("e&{}: could not connect", name); } - time::sleep(Duration::from_secs(5)).await; // TODO Make configurable + tokio::time::sleep(Duration::from_secs(5)).await; // TODO Make configurable } } @@ -103,7 +103,7 @@ impl State { async fn regularly_request_logs(event_tx: &mpsc::UnboundedSender) { loop { - time::sleep(Duration::from_secs(2)).await; // TODO Make configurable + tokio::time::sleep(Duration::from_secs(2)).await; // TODO Make configurable let _ = event_tx.send(Event::RequestLogs); } } @@ -171,7 +171,7 @@ impl State { } Data::SnapshotEvent(d) => { info!("e&{}: successfully joined", self.name); - self.vault.join(Utc::now()); + self.vault.join(OffsetDateTime::now_utc()); self.last_msg_id = Some(d.log.last().map(|m| m.id)); self.vault.add_messages(d.log, None); } diff --git a/src/export.rs b/src/export.rs index 7a97b90..6a3033e 100644 --- a/src/export.rs +++ b/src/export.rs @@ -4,13 +4,16 @@ use std::fs::File; use std::io::{BufWriter, Write}; use std::path::Path; +use time::format_description::FormatItem; +use time::macros::format_description; use unicode_width::UnicodeWidthStr; use crate::euph::api::Snowflake; use crate::store::{MsgStore, Tree}; use crate::vault::{EuphMsg, Vault}; -const TIME_FORMAT: &str = "%F %T"; +const TIME_FORMAT: &[FormatItem<'_>] = + format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"); const TIME_EMPTY: &str = " "; pub async fn export(vault: &Vault, room: String, file: &Path) -> anyhow::Result<()> { @@ -67,7 +70,11 @@ fn write_msg(file: &mut BufWriter, indent_string: &str, msg: &EuphMsg) -> for (i, line) in msg.content.lines().enumerate() { if i == 0 { - let time = msg.time.0.format(TIME_FORMAT); + let time = msg + .time + .0 + .format(TIME_FORMAT) + .expect("time can be formatted"); writeln!(file, "{time} {indent_string}[{nick}] {line}")?; } else { writeln!(file, "{TIME_EMPTY} {indent_string}| {nick_empty} {line}")?; diff --git a/src/logger.rs b/src/logger.rs index fe0aa91..9194c6a 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -2,10 +2,10 @@ use std::sync::Arc; use std::vec; use async_trait::async_trait; -use chrono::{DateTime, Utc}; use crossterm::style::{ContentStyle, Stylize}; use log::{Level, Log}; use parking_lot::Mutex; +use time::OffsetDateTime; use tokio::sync::mpsc; use toss::styled::Styled; @@ -14,7 +14,7 @@ use crate::store::{Msg, MsgStore, Path, Tree}; #[derive(Debug, Clone)] pub struct LogMsg { id: usize, - time: DateTime, + time: OffsetDateTime, level: Level, content: String, } @@ -30,7 +30,7 @@ impl Msg for LogMsg { None } - fn time(&self) -> DateTime { + fn time(&self) -> OffsetDateTime { self.time } @@ -109,7 +109,7 @@ impl Log for Logger { let mut guard = self.messages.lock(); let msg = LogMsg { id: guard.len(), - time: Utc::now(), + time: OffsetDateTime::now_utc(), level: record.level(), content: format!("<{}> {}", record.target(), record.args()), }; diff --git a/src/store.rs b/src/store.rs index ce2a816..e0898da 100644 --- a/src/store.rs +++ b/src/store.rs @@ -4,7 +4,7 @@ use std::hash::Hash; use std::vec; use async_trait::async_trait; -use chrono::{DateTime, Utc}; +use time::OffsetDateTime; use toss::styled::Styled; pub trait Msg { @@ -12,7 +12,7 @@ pub trait Msg { fn id(&self) -> Self::Id; fn parent(&self) -> Option; - fn time(&self) -> DateTime; + fn time(&self) -> OffsetDateTime; fn nick(&self) -> Styled; fn content(&self) -> Styled; diff --git a/src/ui/chat/tree/blocks.rs b/src/ui/chat/tree/blocks.rs index f97696c..5d8786f 100644 --- a/src/ui/chat/tree/blocks.rs +++ b/src/ui/chat/tree/blocks.rs @@ -3,7 +3,7 @@ use std::collections::{vec_deque, VecDeque}; use std::iter; -use chrono::{DateTime, Utc}; +use time::OffsetDateTime; use toss::styled::Styled; use crate::macros::some_or_return; @@ -50,7 +50,7 @@ pub enum BlockBody { #[derive(Debug, Clone)] pub struct Block { pub line: i32, - pub time: Option>, + pub time: Option, pub indent: usize, pub body: BlockBody, } @@ -75,7 +75,7 @@ impl Block { } pub fn msg( - time: DateTime, + time: OffsetDateTime, indent: usize, id: I, nick: Styled, @@ -92,7 +92,7 @@ impl Block { } } - pub fn placeholder(time: Option>, indent: usize, id: I) -> Self { + pub fn placeholder(time: Option, indent: usize, id: I) -> Self { Self { line: 0, time, diff --git a/src/ui/chat/tree/render.rs b/src/ui/chat/tree/render.rs index 08f81ea..e649e55 100644 --- a/src/ui/chat/tree/render.rs +++ b/src/ui/chat/tree/render.rs @@ -1,6 +1,6 @@ //! Rendering blocks to a [`Frame`]. -use chrono::{DateTime, Utc}; +use time::OffsetDateTime; use toss::frame::{Frame, Pos}; use toss::styled::Styled; @@ -10,7 +10,7 @@ use super::blocks::{Block, BlockBody, MsgBlock, MsgContent}; use super::{util, InnerTreeViewState}; impl> InnerTreeViewState { - fn render_time(frame: &mut Frame, line: i32, time: Option>, is_cursor: bool) { + fn render_time(frame: &mut Frame, line: i32, time: Option, is_cursor: bool) { let pos = Pos::new(0, line); let style = if is_cursor { util::style_time_inverted() @@ -19,7 +19,9 @@ impl> InnerTreeViewState { }; if let Some(time) = time { - let time = format!("{}", time.format(util::TIME_FORMAT)); + let time = time + .format(util::TIME_FORMAT) + .expect("time can be formatted"); frame.write(pos, (&time, style)); } else { frame.write(pos, (util::TIME_EMPTY, style)); @@ -51,7 +53,7 @@ impl> InnerTreeViewState { fn draw_msg_block( frame: &mut Frame, line: i32, - time: Option>, + time: Option, indent: usize, msg: &MsgBlock, is_cursor: bool, diff --git a/src/ui/chat/tree/util.rs b/src/ui/chat/tree/util.rs index 29d8bfa..2683acb 100644 --- a/src/ui/chat/tree/util.rs +++ b/src/ui/chat/tree/util.rs @@ -1,10 +1,13 @@ //! Constants and helper functions. use crossterm::style::{ContentStyle, Stylize}; +use time::format_description::FormatItem; +use time::macros::format_description; use toss::frame::Frame; use toss::styled::Styled; -pub const TIME_FORMAT: &str = "%F %R "; +pub const TIME_FORMAT: &[FormatItem<'_>] = + format_description!("[year]-[month]-[day] [hour]:[minute] "); pub const TIME_EMPTY: &str = " "; pub const TIME_WIDTH: usize = TIME_EMPTY.len(); diff --git a/src/vault/euph.rs b/src/vault/euph.rs index ea8cb95..a8f02ed 100644 --- a/src/vault/euph.rs +++ b/src/vault/euph.rs @@ -1,9 +1,9 @@ use std::mem; use async_trait::async_trait; -use chrono::{DateTime, Utc}; use rusqlite::types::{FromSql, FromSqlError, ToSqlOutput, Value, ValueRef}; use rusqlite::{named_params, params, Connection, OptionalExtension, ToSql, Transaction}; +use time::OffsetDateTime; use tokio::sync::{mpsc, oneshot}; use toss::styled::Styled; @@ -27,7 +27,7 @@ impl FromSql for Snowflake { impl ToSql for Time { fn to_sql(&self) -> rusqlite::Result> { - let timestamp = self.0.timestamp(); + let timestamp = self.0.unix_timestamp(); Ok(ToSqlOutput::Owned(Value::Integer(timestamp))) } } @@ -35,7 +35,9 @@ impl ToSql for Time { impl FromSql for Time { fn column_result(value: ValueRef<'_>) -> rusqlite::types::FromSqlResult { let timestamp = i64::column_result(value)?; - Ok(Self::new(timestamp)) + Ok(Self( + OffsetDateTime::from_unix_timestamp(timestamp).expect("timestamp in range"), + )) } } @@ -59,7 +61,7 @@ impl Msg for EuphMsg { self.parent } - fn time(&self) -> DateTime { + fn time(&self) -> OffsetDateTime { self.time.0 } @@ -103,7 +105,7 @@ impl EuphVault { &self.room } - pub fn join(&self, time: DateTime) { + pub fn join(&self, time: OffsetDateTime) { let request = EuphRequest::Join { room: self.room.clone(), time, @@ -225,7 +227,7 @@ pub(super) enum EuphRequest { }, Join { room: String, - time: DateTime, + time: OffsetDateTime, }, Delete { room: String, @@ -325,7 +327,7 @@ impl EuphRequest { Ok(()) } - fn join(conn: &mut Connection, room: String, time: DateTime) -> rusqlite::Result<()> { + fn join(conn: &mut Connection, room: String, time: OffsetDateTime) -> rusqlite::Result<()> { conn.execute( " INSERT INTO euph_rooms (room, first_joined, last_joined)