Replace chrono dependency by time

This commit is contained in:
Joscha 2022-07-24 17:12:22 +02:00
parent 4e014168b4
commit 8bc7af0d3f
11 changed files with 76 additions and 76 deletions

63
Cargo.lock generated
View file

@ -116,20 +116,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 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]] [[package]]
name = "clap" name = "clap"
version = "3.2.12" version = "3.2.12"
@ -191,7 +177,6 @@ version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
"chrono",
"clap", "clap",
"crossterm", "crossterm",
"directories", "directories",
@ -205,6 +190,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "thiserror",
"time",
"tokio", "tokio",
"tokio-tungstenite", "tokio-tungstenite",
"toss", "toss",
@ -455,7 +441,7 @@ checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"wasi 0.11.0+wasi-snapshot-preview1", "wasi",
] ]
[[package]] [[package]]
@ -615,20 +601,10 @@ checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf"
dependencies = [ dependencies = [
"libc", "libc",
"log", "log",
"wasi 0.11.0+wasi-snapshot-preview1", "wasi",
"windows-sys", "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]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.15" version = "0.2.15"
@ -648,6 +624,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "num_threads"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.13.0" version = "1.13.0"
@ -882,12 +867,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"chrono",
"fallible-iterator", "fallible-iterator",
"fallible-streaming-iterator", "fallible-streaming-iterator",
"hashlink", "hashlink",
"libsqlite3-sys", "libsqlite3-sys",
"smallvec", "smallvec",
"time",
] ]
[[package]] [[package]]
@ -1146,15 +1131,23 @@ dependencies = [
[[package]] [[package]]
name = "time" name = "time"
version = "0.1.44" version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217"
dependencies = [ dependencies = [
"itoa",
"libc", "libc",
"wasi 0.10.0+wasi-snapshot-preview1", "num_threads",
"winapi", "serde",
"time-macros",
] ]
[[package]]
name = "time-macros"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792"
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.6.0" version = "1.6.0"
@ -1354,12 +1347,6 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 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]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.0+wasi-snapshot-preview1" version = "0.11.0+wasi-snapshot-preview1"

View file

@ -6,7 +6,6 @@ edition = "2021"
[dependencies] [dependencies]
anyhow = "1.0.58" anyhow = "1.0.58"
async-trait = "0.1.56" async-trait = "0.1.56"
chrono = { version = "0.4.19", features = ["serde"] }
clap = { version = "3.2.12", features = ["derive"] } clap = { version = "3.2.12", features = ["derive"] }
crossterm = "0.24.0" crossterm = "0.24.0"
directories = "4.0.1" 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"] } palette = { version = "0.6.0", default-features = false, features = ["std"] }
parking_lot = "0.12.1" parking_lot = "0.12.1"
rand = "0.8.5" 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 = { version = "1.0.139", features = ["derive"] }
serde_json = "1.0.82" serde_json = "1.0.82"
thiserror = "1.0.31" thiserror = "1.0.31"
@ -24,6 +23,10 @@ tokio = { version = "1.20.0", features = ["full"] }
unicode-segmentation = "1.9.0" unicode-segmentation = "1.9.0"
unicode-width = "0.1.9" unicode-width = "0.1.9"
[dependencies.time]
version = "0.3.11"
features = ["macros", "formatting", "parsing", "serde"]
[dependencies.tokio-tungstenite] [dependencies.tokio-tungstenite]
version = "0.17.2" version = "0.17.2"
features = ["rustls-tls-native-roots"] features = ["rustls-tls-native-roots"]

View file

@ -8,9 +8,9 @@
use std::fmt; use std::fmt;
use chrono::{DateTime, TimeZone, Utc};
use serde::{de, ser, Deserialize, Serialize}; use serde::{de, ser, Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
use time::OffsetDateTime;
/// Describes an account and its preferred name. /// Describes an account and its preferred name.
#[derive(Debug, Clone, Serialize, Deserialize)] #[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 /// Time is specified as a signed 64-bit integer, giving the number of seconds
/// since the Unix Epoch. /// since the Unix Epoch.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct Time(#[serde(with = "chrono::serde::ts_seconds")] pub DateTime<Utc>); pub struct Time(#[serde(with = "time::serde::timestamp")] pub OffsetDateTime);
impl Time { impl Time {
pub fn new(timestamp: i64) -> Self {
Self(Utc.timestamp(timestamp, 0))
}
pub fn now() -> Self { pub fn now() -> Self {
Self::new(Utc::now().timestamp()) Self(OffsetDateTime::now_utc().replace_millisecond(0).unwrap())
} }
} }

View file

@ -3,11 +3,11 @@ use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use anyhow::bail; use anyhow::bail;
use chrono::Utc;
use log::{error, info, warn}; use log::{error, info, warn};
use parking_lot::Mutex; use parking_lot::Mutex;
use time::OffsetDateTime;
use tokio::sync::{mpsc, oneshot}; use tokio::sync::{mpsc, oneshot};
use tokio::{select, task, time}; use tokio::{select, task};
use tokio_tungstenite::tungstenite; use tokio_tungstenite::tungstenite;
use crate::ui::UiEvent; use crate::ui::UiEvent;
@ -82,7 +82,7 @@ impl State {
} else { } else {
info!("e&{}: could not connect", name); 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<Event>) { async fn regularly_request_logs(event_tx: &mpsc::UnboundedSender<Event>) {
loop { 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); let _ = event_tx.send(Event::RequestLogs);
} }
} }
@ -171,7 +171,7 @@ impl State {
} }
Data::SnapshotEvent(d) => { Data::SnapshotEvent(d) => {
info!("e&{}: successfully joined", self.name); 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.last_msg_id = Some(d.log.last().map(|m| m.id));
self.vault.add_messages(d.log, None); self.vault.add_messages(d.log, None);
} }

View file

@ -4,13 +4,16 @@ use std::fs::File;
use std::io::{BufWriter, Write}; use std::io::{BufWriter, Write};
use std::path::Path; use std::path::Path;
use time::format_description::FormatItem;
use time::macros::format_description;
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
use crate::euph::api::Snowflake; use crate::euph::api::Snowflake;
use crate::store::{MsgStore, Tree}; use crate::store::{MsgStore, Tree};
use crate::vault::{EuphMsg, Vault}; 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 = " "; const TIME_EMPTY: &str = " ";
pub async fn export(vault: &Vault, room: String, file: &Path) -> anyhow::Result<()> { pub async fn export(vault: &Vault, room: String, file: &Path) -> anyhow::Result<()> {
@ -67,7 +70,11 @@ fn write_msg(file: &mut BufWriter<File>, indent_string: &str, msg: &EuphMsg) ->
for (i, line) in msg.content.lines().enumerate() { for (i, line) in msg.content.lines().enumerate() {
if i == 0 { 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}")?; writeln!(file, "{time} {indent_string}[{nick}] {line}")?;
} else { } else {
writeln!(file, "{TIME_EMPTY} {indent_string}| {nick_empty} {line}")?; writeln!(file, "{TIME_EMPTY} {indent_string}| {nick_empty} {line}")?;

View file

@ -2,10 +2,10 @@ use std::sync::Arc;
use std::vec; use std::vec;
use async_trait::async_trait; use async_trait::async_trait;
use chrono::{DateTime, Utc};
use crossterm::style::{ContentStyle, Stylize}; use crossterm::style::{ContentStyle, Stylize};
use log::{Level, Log}; use log::{Level, Log};
use parking_lot::Mutex; use parking_lot::Mutex;
use time::OffsetDateTime;
use tokio::sync::mpsc; use tokio::sync::mpsc;
use toss::styled::Styled; use toss::styled::Styled;
@ -14,7 +14,7 @@ use crate::store::{Msg, MsgStore, Path, Tree};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct LogMsg { pub struct LogMsg {
id: usize, id: usize,
time: DateTime<Utc>, time: OffsetDateTime,
level: Level, level: Level,
content: String, content: String,
} }
@ -30,7 +30,7 @@ impl Msg for LogMsg {
None None
} }
fn time(&self) -> DateTime<Utc> { fn time(&self) -> OffsetDateTime {
self.time self.time
} }
@ -109,7 +109,7 @@ impl Log for Logger {
let mut guard = self.messages.lock(); let mut guard = self.messages.lock();
let msg = LogMsg { let msg = LogMsg {
id: guard.len(), id: guard.len(),
time: Utc::now(), time: OffsetDateTime::now_utc(),
level: record.level(), level: record.level(),
content: format!("<{}> {}", record.target(), record.args()), content: format!("<{}> {}", record.target(), record.args()),
}; };

View file

@ -4,7 +4,7 @@ use std::hash::Hash;
use std::vec; use std::vec;
use async_trait::async_trait; use async_trait::async_trait;
use chrono::{DateTime, Utc}; use time::OffsetDateTime;
use toss::styled::Styled; use toss::styled::Styled;
pub trait Msg { pub trait Msg {
@ -12,7 +12,7 @@ pub trait Msg {
fn id(&self) -> Self::Id; fn id(&self) -> Self::Id;
fn parent(&self) -> Option<Self::Id>; fn parent(&self) -> Option<Self::Id>;
fn time(&self) -> DateTime<Utc>; fn time(&self) -> OffsetDateTime;
fn nick(&self) -> Styled; fn nick(&self) -> Styled;
fn content(&self) -> Styled; fn content(&self) -> Styled;

View file

@ -3,7 +3,7 @@
use std::collections::{vec_deque, VecDeque}; use std::collections::{vec_deque, VecDeque};
use std::iter; use std::iter;
use chrono::{DateTime, Utc}; use time::OffsetDateTime;
use toss::styled::Styled; use toss::styled::Styled;
use crate::macros::some_or_return; use crate::macros::some_or_return;
@ -50,7 +50,7 @@ pub enum BlockBody<I> {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Block<I> { pub struct Block<I> {
pub line: i32, pub line: i32,
pub time: Option<DateTime<Utc>>, pub time: Option<OffsetDateTime>,
pub indent: usize, pub indent: usize,
pub body: BlockBody<I>, pub body: BlockBody<I>,
} }
@ -75,7 +75,7 @@ impl<I> Block<I> {
} }
pub fn msg( pub fn msg(
time: DateTime<Utc>, time: OffsetDateTime,
indent: usize, indent: usize,
id: I, id: I,
nick: Styled, nick: Styled,
@ -92,7 +92,7 @@ impl<I> Block<I> {
} }
} }
pub fn placeholder(time: Option<DateTime<Utc>>, indent: usize, id: I) -> Self { pub fn placeholder(time: Option<OffsetDateTime>, indent: usize, id: I) -> Self {
Self { Self {
line: 0, line: 0,
time, time,

View file

@ -1,6 +1,6 @@
//! Rendering blocks to a [`Frame`]. //! Rendering blocks to a [`Frame`].
use chrono::{DateTime, Utc}; use time::OffsetDateTime;
use toss::frame::{Frame, Pos}; use toss::frame::{Frame, Pos};
use toss::styled::Styled; use toss::styled::Styled;
@ -10,7 +10,7 @@ use super::blocks::{Block, BlockBody, MsgBlock, MsgContent};
use super::{util, InnerTreeViewState}; use super::{util, InnerTreeViewState};
impl<M: Msg, S: MsgStore<M>> InnerTreeViewState<M, S> { impl<M: Msg, S: MsgStore<M>> InnerTreeViewState<M, S> {
fn render_time(frame: &mut Frame, line: i32, time: Option<DateTime<Utc>>, is_cursor: bool) { fn render_time(frame: &mut Frame, line: i32, time: Option<OffsetDateTime>, is_cursor: bool) {
let pos = Pos::new(0, line); let pos = Pos::new(0, line);
let style = if is_cursor { let style = if is_cursor {
util::style_time_inverted() util::style_time_inverted()
@ -19,7 +19,9 @@ impl<M: Msg, S: MsgStore<M>> InnerTreeViewState<M, S> {
}; };
if let Some(time) = time { 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)); frame.write(pos, (&time, style));
} else { } else {
frame.write(pos, (util::TIME_EMPTY, style)); frame.write(pos, (util::TIME_EMPTY, style));
@ -51,7 +53,7 @@ impl<M: Msg, S: MsgStore<M>> InnerTreeViewState<M, S> {
fn draw_msg_block( fn draw_msg_block(
frame: &mut Frame, frame: &mut Frame,
line: i32, line: i32,
time: Option<DateTime<Utc>>, time: Option<OffsetDateTime>,
indent: usize, indent: usize,
msg: &MsgBlock<M::Id>, msg: &MsgBlock<M::Id>,
is_cursor: bool, is_cursor: bool,

View file

@ -1,10 +1,13 @@
//! Constants and helper functions. //! Constants and helper functions.
use crossterm::style::{ContentStyle, Stylize}; use crossterm::style::{ContentStyle, Stylize};
use time::format_description::FormatItem;
use time::macros::format_description;
use toss::frame::Frame; use toss::frame::Frame;
use toss::styled::Styled; 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_EMPTY: &str = " ";
pub const TIME_WIDTH: usize = TIME_EMPTY.len(); pub const TIME_WIDTH: usize = TIME_EMPTY.len();

View file

@ -1,9 +1,9 @@
use std::mem; use std::mem;
use async_trait::async_trait; use async_trait::async_trait;
use chrono::{DateTime, Utc};
use rusqlite::types::{FromSql, FromSqlError, ToSqlOutput, Value, ValueRef}; use rusqlite::types::{FromSql, FromSqlError, ToSqlOutput, Value, ValueRef};
use rusqlite::{named_params, params, Connection, OptionalExtension, ToSql, Transaction}; use rusqlite::{named_params, params, Connection, OptionalExtension, ToSql, Transaction};
use time::OffsetDateTime;
use tokio::sync::{mpsc, oneshot}; use tokio::sync::{mpsc, oneshot};
use toss::styled::Styled; use toss::styled::Styled;
@ -27,7 +27,7 @@ impl FromSql for Snowflake {
impl ToSql for Time { impl ToSql for Time {
fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> { fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> {
let timestamp = self.0.timestamp(); let timestamp = self.0.unix_timestamp();
Ok(ToSqlOutput::Owned(Value::Integer(timestamp))) Ok(ToSqlOutput::Owned(Value::Integer(timestamp)))
} }
} }
@ -35,7 +35,9 @@ impl ToSql for Time {
impl FromSql for Time { impl FromSql for Time {
fn column_result(value: ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> {
let timestamp = i64::column_result(value)?; 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 self.parent
} }
fn time(&self) -> DateTime<Utc> { fn time(&self) -> OffsetDateTime {
self.time.0 self.time.0
} }
@ -103,7 +105,7 @@ impl EuphVault {
&self.room &self.room
} }
pub fn join(&self, time: DateTime<Utc>) { pub fn join(&self, time: OffsetDateTime) {
let request = EuphRequest::Join { let request = EuphRequest::Join {
room: self.room.clone(), room: self.room.clone(),
time, time,
@ -225,7 +227,7 @@ pub(super) enum EuphRequest {
}, },
Join { Join {
room: String, room: String,
time: DateTime<Utc>, time: OffsetDateTime,
}, },
Delete { Delete {
room: String, room: String,
@ -325,7 +327,7 @@ impl EuphRequest {
Ok(()) Ok(())
} }
fn join(conn: &mut Connection, room: String, time: DateTime<Utc>) -> rusqlite::Result<()> { fn join(conn: &mut Connection, room: String, time: OffsetDateTime) -> rusqlite::Result<()> {
conn.execute( conn.execute(
" "
INSERT INTO euph_rooms (room, first_joined, last_joined) INSERT INTO euph_rooms (room, first_joined, last_joined)