diff options
author | Conrad Ludgate <conradludgate@gmail.com> | 2023-09-11 09:26:05 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-11 09:26:05 +0100 |
commit | f90c01f702f6a98b041f766b6a1d857bc1b9afef (patch) | |
tree | 04a4755bd632abdcf398d0ce903163ed60a5a212 | |
parent | 2342a3392349c0ae9d742e9da9833590e6567d08 (diff) |
replace chrono with time (#806)
* replace chrono with time
* Fix test chrono usage
---------
Co-authored-by: Ellie Huxtable <ellie@elliehuxtable.com>
35 files changed, 358 insertions, 385 deletions
@@ -55,15 +55,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] name = "anstream" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -160,7 +151,6 @@ dependencies = [ "atuin-server", "atuin-server-postgres", "base64 0.21.2", - "chrono", "clap", "clap_complete", "colored", @@ -181,6 +171,7 @@ dependencies = [ "semver", "serde", "serde_json", + "time", "tiny-bip39", "tokio", "tracing", @@ -197,7 +188,6 @@ dependencies = [ "async-trait", "atuin-common", "base64 0.21.2", - "chrono", "clap", "config", "crypto_secretbox", @@ -229,6 +219,7 @@ dependencies = [ "shellexpand", "sql-builder", "sqlx", + "time", "tokio", "typed-builder", "urlencoding", @@ -240,12 +231,12 @@ dependencies = [ name = "atuin-common" version = "16.0.0" dependencies = [ - "chrono", "eyre", "pretty_assertions", "rand 0.8.5", "serde", "sqlx", + "time", "typed-builder", "uuid", ] @@ -260,8 +251,6 @@ dependencies = [ "atuin-server-database", "axum", "base64 0.21.2", - "chrono", - "chronoutil", "config", "eyre", "fs-err", @@ -271,6 +260,7 @@ dependencies = [ "semver", "serde", "serde_json", + "time", "tokio", "tower", "tower-http", @@ -284,10 +274,9 @@ version = "16.0.0" dependencies = [ "async-trait", "atuin-common", - "chrono", - "chronoutil", "eyre", "serde", + "time", "tracing", "uuid", ] @@ -299,10 +288,10 @@ dependencies = [ "async-trait", "atuin-common", "atuin-server-database", - "chrono", "futures-util", "serde", "sqlx", + "time", "tracing", "uuid", ] @@ -516,31 +505,6 @@ dependencies = [ ] [[package]] -name = "chrono" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" -dependencies = [ - "iana-time-zone", - "js-sys", - "num-integer", - "num-traits", - "serde", - "time 0.1.45", - "wasm-bindgen", - "winapi", -] - -[[package]] -name = "chronoutil" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a58c924bb772aa201da3acf5308c46b60275c64e6d3bc89c23dd63d71e83fd" -dependencies = [ - "chrono", -] - -[[package]] name = "cipher" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -838,6 +802,9 @@ name = "deranged" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" +dependencies = [ + "serde", +] [[package]] name = "diff" @@ -1420,29 +1387,6 @@ dependencies = [ ] [[package]] -name = "iana-time-zone" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] name = "idna" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1521,8 +1465,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ffd2ac8397b9574daa4ffa7ede4427dd249cadaa900719d4b01154a5631d38b" dependencies = [ - "chrono", "logos", + "time", ] [[package]] @@ -1847,6 +1791,15 @@ dependencies = [ ] [[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + +[[package]] name = "number_prefix" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2478,7 +2431,7 @@ dependencies = [ "iso8601", "ring", "thiserror", - "time 0.3.25", + "time", "zeroize", ] @@ -2817,7 +2770,6 @@ dependencies = [ "atoi", "byteorder", "bytes", - "chrono", "crc", "crossbeam-queue", "dotenvy", @@ -2844,6 +2796,7 @@ dependencies = [ "smallvec", "sqlformat", "thiserror", + "time", "tokio", "tokio-stream", "tracing", @@ -2902,7 +2855,6 @@ dependencies = [ "bitflags 2.4.0", "byteorder", "bytes", - "chrono", "crc", "digest 0.10.7", "dotenvy", @@ -2930,6 +2882,7 @@ dependencies = [ "sqlx-core", "stringprep", "thiserror", + "time", "tracing", "uuid", "whoami", @@ -2945,7 +2898,6 @@ dependencies = [ "base64 0.21.2", "bitflags 2.4.0", "byteorder", - "chrono", "crc", "dotenvy", "etcetera", @@ -2971,6 +2923,7 @@ dependencies = [ "sqlx-core", "stringprep", "thiserror", + "time", "tracing", "uuid", "whoami", @@ -2983,7 +2936,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4c21bf34c7cae5b283efb3ac1bcc7670df7561124dc2f8bdc0b59be40f79a2" dependencies = [ "atoi", - "chrono", "flume", "futures-channel", "futures-core", @@ -2995,6 +2947,7 @@ dependencies = [ "percent-encoding", "serde", "sqlx-core", + "time", "tracing", "url", "uuid", @@ -3104,23 +3057,14 @@ dependencies = [ [[package]] name = "time" -version = "0.1.45" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "time" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" +checksum = "a79d09ac6b08c1ab3906a2f7cc2e81a0e27c7ae89c63812df75e52bef0751e07" dependencies = [ "deranged", "itoa", + "libc", + "num_threads", "serde", "time-core", "time-macros", @@ -3134,9 +3078,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" +checksum = "75c65469ed6b3a4809d987a41eb1dc918e9bc1d92211cbad7ae82931846f7451" dependencies = [ "time-core", ] @@ -3525,12 +3469,6 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" @@ -3662,15 +3600,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] name = "windows-sys" version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -12,7 +12,7 @@ members = [ name = "atuin" version = "16.0.0" authors = ["Ellie Huxtable <ellie@elliehuxtable.com>"] -rust-version = "1.59" +rust-version = "1.67" license = "MIT" homepage = "https://atuin.sh" repository = "https://github.com/atuinsh/atuin" @@ -22,13 +22,13 @@ readme = "README.md" async-trait = "0.1.58" base64 = "0.21" log = "0.4" -chrono = { version = "0.4", features = ["serde"] } +time = { version = "0.3", features = ["serde-human-readable", "macros", "local-offset"] } clap = { version = "4.0.18", features = ["derive"] } config = { version = "0.13", default-features = false, features = ["toml"] } directories = "4" eyre = "0.6" fs-err = "2.9" -interim = { version = "0.1.0", features = ["chrono"] } +interim = { version = "0.1.0", features = ["time"] } itertools = "0.10.5" rand = { version = "0.8.5", features = ["std"] } semver = "1.0.14" @@ -50,4 +50,9 @@ default-features = false [workspace.dependencies.sqlx] version = "0.7.1" -features = ["runtime-tokio-rustls", "chrono", "postgres", "uuid"] +features = [ + "runtime-tokio-rustls", + "time", + "postgres", + "uuid", +] diff --git a/atuin-client/Cargo.toml b/atuin-client/Cargo.toml index 732b6a74..9e8a050d 100644 --- a/atuin-client/Cargo.toml +++ b/atuin-client/Cargo.toml @@ -3,6 +3,7 @@ name = "atuin-client" edition = "2021" description = "client library for atuin" +rust-version = { workspace = true } version = { workspace = true } authors = { workspace = true } license = { workspace = true } @@ -20,7 +21,7 @@ atuin-common = { path = "../atuin-common", version = "16.0.0" } log = { workspace = true } base64 = { workspace = true } -chrono = { workspace = true } +time = { workspace = true } clap = { workspace = true } eyre = { workspace = true } directories = { workspace = true } diff --git a/atuin-client/src/api_client.rs b/atuin-client/src/api_client.rs index 5ae1ed0a..d2ca339f 100644 --- a/atuin-client/src/api_client.rs +++ b/atuin-client/src/api_client.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use std::env; -use chrono::Utc; use eyre::{bail, Result}; use reqwest::{ header::{HeaderMap, AUTHORIZATION, USER_AGENT}, @@ -17,6 +16,8 @@ use atuin_common::{ record::RecordIndex, }; use semver::Version; +use time::format_description::well_known::Rfc3339; +use time::OffsetDateTime; use crate::{history::History, sync::hash_str}; @@ -150,8 +151,8 @@ impl<'a> Client<'a> { pub async fn get_history( &self, - sync_ts: chrono::DateTime<Utc>, - history_ts: chrono::DateTime<Utc>, + sync_ts: OffsetDateTime, + history_ts: OffsetDateTime, host: Option<String>, ) -> Result<SyncHistoryResponse> { let host = host.unwrap_or_else(|| { @@ -165,8 +166,8 @@ impl<'a> Client<'a> { let url = format!( "{}/sync/history?sync_ts={}&history_ts={}&host={}", self.sync_addr, - urlencoding::encode(sync_ts.to_rfc3339().as_str()), - urlencoding::encode(history_ts.to_rfc3339().as_str()), + urlencoding::encode(sync_ts.format(&Rfc3339)?.as_str()), + urlencoding::encode(history_ts.format(&Rfc3339)?.as_str()), host, ); diff --git a/atuin-client/src/database.rs b/atuin-client/src/database.rs index b69c7cb2..16a4a43f 100644 --- a/atuin-client/src/database.rs +++ b/atuin-client/src/database.rs @@ -6,7 +6,6 @@ use std::{ use async_trait::async_trait; use atuin_common::utils; -use chrono::{prelude::*, Utc}; use fs_err as fs; use itertools::Itertools; use lazy_static::lazy_static; @@ -17,6 +16,7 @@ use sqlx::{ sqlite::{SqliteConnectOptions, SqliteJournalMode, SqlitePool, SqlitePoolOptions, SqliteRow}, Result, Row, }; +use time::OffsetDateTime; use super::{ history::History, @@ -81,18 +81,14 @@ pub trait Database: Send + Sync + 'static { max: Option<usize>, unique: bool, ) -> Result<Vec<History>>; - async fn range( - &self, - from: chrono::DateTime<Utc>, - to: chrono::DateTime<Utc>, - ) -> Result<Vec<History>>; + async fn range(&self, from: OffsetDateTime, to: OffsetDateTime) -> Result<Vec<History>>; async fn update(&self, h: &History) -> Result<()>; async fn history_count(&self) -> Result<i64>; async fn first(&self) -> Result<History>; async fn last(&self) -> Result<History>; - async fn before(&self, timestamp: chrono::DateTime<Utc>, count: i64) -> Result<Vec<History>>; + async fn before(&self, timestamp: OffsetDateTime, count: i64) -> Result<Vec<History>>; async fn delete(&self, mut h: History) -> Result<()>; async fn deleted(&self) -> Result<Vec<History>>; @@ -158,14 +154,14 @@ impl Sqlite { values(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9)", ) .bind(h.id.as_str()) - .bind(h.timestamp.timestamp_nanos()) + .bind(h.timestamp.unix_timestamp_nanos() as i64) .bind(h.duration) .bind(h.exit) .bind(h.command.as_str()) .bind(h.cwd.as_str()) .bind(h.session.as_str()) .bind(h.hostname.as_str()) - .bind(h.deleted_at.map(|t|t.timestamp_nanos())) + .bind(h.deleted_at.map(|t|t.unix_timestamp_nanos() as i64)) .execute(&mut **tx) .await?; @@ -177,14 +173,19 @@ impl Sqlite { History::from_db() .id(row.get("id")) - .timestamp(Utc.timestamp_nanos(row.get("timestamp"))) + .timestamp( + OffsetDateTime::from_unix_timestamp_nanos(row.get::<i64, _>("timestamp") as i128) + .unwrap(), + ) .duration(row.get("duration")) .exit(row.get("exit")) .command(row.get("command")) .cwd(row.get("cwd")) .session(row.get("session")) .hostname(row.get("hostname")) - .deleted_at(deleted_at.map(|t| Utc.timestamp_nanos(t))) + .deleted_at( + deleted_at.and_then(|t| OffsetDateTime::from_unix_timestamp_nanos(t as i128).ok()), + ) .build() .into() } @@ -236,14 +237,14 @@ impl Database for Sqlite { where id = ?1", ) .bind(h.id.as_str()) - .bind(h.timestamp.timestamp_nanos()) + .bind(h.timestamp.unix_timestamp_nanos() as i64) .bind(h.duration) .bind(h.exit) .bind(h.command.as_str()) .bind(h.cwd.as_str()) .bind(h.session.as_str()) .bind(h.hostname.as_str()) - .bind(h.deleted_at.map(|t|t.timestamp_nanos())) + .bind(h.deleted_at.map(|t|t.unix_timestamp_nanos() as i64)) .execute(&self.pool) .await?; @@ -292,18 +293,14 @@ impl Database for Sqlite { Ok(res) } - async fn range( - &self, - from: chrono::DateTime<Utc>, - to: chrono::DateTime<Utc>, - ) -> Result<Vec<History>> { + async fn range(&self, from: OffsetDateTime, to: OffsetDateTime) -> Result<Vec<History>> { debug!("listing history from {:?} to {:?}", from, to); let res = sqlx::query( "select * from history where timestamp >= ?1 and timestamp <= ?2 order by timestamp asc", ) - .bind(from.timestamp_nanos()) - .bind(to.timestamp_nanos()) + .bind(from.unix_timestamp_nanos() as i64) + .bind(to.unix_timestamp_nanos() as i64) .map(Self::query_history) .fetch_all(&self.pool) .await?; @@ -332,11 +329,11 @@ impl Database for Sqlite { Ok(res) } - async fn before(&self, timestamp: chrono::DateTime<Utc>, count: i64) -> Result<Vec<History>> { + async fn before(&self, timestamp: OffsetDateTime, count: i64) -> Result<Vec<History>> { let res = sqlx::query( "select * from history where timestamp < ?1 order by timestamp desc limit ?2", ) - .bind(timestamp.timestamp_nanos()) + .bind(timestamp.unix_timestamp_nanos() as i64) .bind(count) .map(Self::query_history) .fetch_all(&self.pool) @@ -471,13 +468,23 @@ impl Database for Sqlite { .map(|exclude_cwd| sql.and_where_ne("cwd", quote(exclude_cwd))); filter_options.before.map(|before| { - interim::parse_date_string(before.as_str(), Utc::now(), interim::Dialect::Uk) - .map(|before| sql.and_where_lt("timestamp", quote(before.timestamp_nanos()))) + interim::parse_date_string( + before.as_str(), + OffsetDateTime::now_utc(), + interim::Dialect::Uk, + ) + .map(|before| { + sql.and_where_lt("timestamp", quote(before.unix_timestamp_nanos() as i64)) + }) }); filter_options.after.map(|after| { - interim::parse_date_string(after.as_str(), Utc::now(), interim::Dialect::Uk) - .map(|after| sql.and_where_gt("timestamp", quote(after.timestamp_nanos()))) + interim::parse_date_string( + after.as_str(), + OffsetDateTime::now_utc(), + interim::Dialect::Uk, + ) + .map(|after| sql.and_where_gt("timestamp", quote(after.unix_timestamp_nanos() as i64))) }); sql.and_where_is_null("deleted_at"); @@ -540,7 +547,7 @@ impl Database for Sqlite { // deleted_at doesn't mean the actual time that the user deleted it, // but the time that the system marks it as deleted async fn delete(&self, mut h: History) -> Result<()> { - let now = chrono::Utc::now(); + let now = OffsetDateTime::now_utc(); h.command = rand::thread_rng() .sample_iter(&Alphanumeric) .take(32) @@ -612,7 +619,7 @@ mod test { async fn new_history_item(db: &mut impl Database, cmd: &str) -> Result<()> { let mut captured: History = History::capture() - .timestamp(chrono::Utc::now()) + .timestamp(OffsetDateTime::now_utc()) .command(cmd) .cwd("/home/ellie") .build() diff --git a/atuin-client/src/encryption.rs b/atuin-client/src/encryption.rs index 056c56d7..f9f8bcb3 100644 --- a/atuin-client/src/encryption.rs +++ b/atuin-client/src/encryption.rs @@ -11,7 +11,6 @@ use std::{io::prelude::*, path::PathBuf}; use base64::prelude::{Engine, BASE64_STANDARD}; -use chrono::{DateTime, Utc}; pub use crypto_secretbox::Key; use crypto_secretbox::{ aead::{Nonce, OsRng}, @@ -21,6 +20,7 @@ use eyre::{bail, ensure, eyre, Context, Result}; use fs_err as fs; use rmp::{decode::Bytes, Marker}; use serde::{Deserialize, Serialize}; +use time::{format_description::well_known::Rfc3339, macros::format_description, OffsetDateTime}; use crate::{history::History, settings::Settings}; @@ -137,6 +137,28 @@ pub fn decrypt(mut encrypted_history: EncryptedHistory, key: &Key) -> Result<His Ok(history) } +fn format_rfc3339(ts: OffsetDateTime) -> Result<String> { + // horrible hack. chrono AutoSI limits to 0, 3, 6, or 9 decimal places for nanoseconds. + // time does not have this functionality. + static PARTIAL_RFC3339_0: &[time::format_description::FormatItem<'static>] = + format_description!("[year]-[month]-[day]T[hour]:[minute]:[second]Z"); + static PARTIAL_RFC3339_3: &[time::format_description::FormatItem<'static>] = + format_description!("[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond digits:3]Z"); + static PARTIAL_RFC3339_6: &[time::format_description::FormatItem<'static>] = + format_description!("[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond digits:6]Z"); + static PARTIAL_RFC3339_9: &[time::format_description::FormatItem<'static>] = + format_description!("[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond digits:9]Z"); + + let fmt = match ts.nanosecond() { + 0 => PARTIAL_RFC3339_0, + ns if ns % 1_000_000 == 0 => PARTIAL_RFC3339_3, + ns if ns % 1_000 == 0 => PARTIAL_RFC3339_6, + _ => PARTIAL_RFC3339_9, + }; + + Ok(ts.format(fmt)?) +} + fn encode(h: &History) -> Result<Vec<u8>> { use rmp::encode; @@ -145,11 +167,7 @@ fn encode(h: &History) -> Result<Vec<u8>> { encode::write_array_len(&mut output, 9)?; encode::write_str(&mut output, &h.id)?; - encode::write_str( - &mut output, - &(h.timestamp - .to_rfc3339_opts(chrono::SecondsFormat::AutoSi, true)), - )?; + encode::write_str(&mut output, &(format_rfc3339(h.timestamp)?))?; encode::write_sint(&mut output, h.duration)?; encode::write_sint(&mut output, h.exit)?; encode::write_str(&mut output, &h.command)?; @@ -157,10 +175,7 @@ fn encode(h: &History) -> Result<Vec<u8>> { encode::write_str(&mut output, &h.session)?; encode::write_str(&mut output, &h.hostname)?; match h.deleted_at { - Some(d) => encode::write_str( - &mut output, - &d.to_rfc3339_opts(chrono::SecondsFormat::AutoSi, true), - )?, + Some(d) => encode::write_str(&mut output, &format_rfc3339(d)?)?, None => encode::write_nil(&mut output)?, } @@ -220,7 +235,7 @@ fn decode(bytes: &[u8]) -> Result<History> { Ok(History { id: id.to_owned(), - timestamp: DateTime::parse_from_rfc3339(timestamp)?.with_timezone(&Utc), + timestamp: OffsetDateTime::parse(timestamp, &Rfc3339)?, duration, exit, command: command.to_owned(), @@ -228,9 +243,8 @@ fn decode(bytes: &[u8]) -> Result<History> { session: session.to_owned(), hostname: hostname.to_owned(), deleted_at: deleted_at - .map(DateTime::parse_from_rfc3339) - .transpose()? - .map(|dt| dt.with_timezone(&Utc)), + .map(|t| OffsetDateTime::parse(t, &Rfc3339)) + .transpose()?, }) } @@ -241,6 +255,8 @@ fn error_report<E: std::fmt::Debug>(err: E) -> eyre::Report { #[cfg(test)] mod test { use crypto_secretbox::{aead::OsRng, KeyInit, XSalsa20Poly1305}; + use pretty_assertions::assert_eq; + use time::{macros::datetime, OffsetDateTime}; use crate::history::History; @@ -253,7 +269,7 @@ mod test { let history = History::from_db() .id("1".into()) - .timestamp(chrono::Utc::now()) + .timestamp(OffsetDateTime::now_utc()) .command("ls".into()) |