questionable: update deps & fix chrono deprecations

possible panic sites are unchanged, they're just more visible now
This commit is contained in:
Vlad Stepanov 2023-04-13 01:19:53 +04:00
parent 198cd0ce6e
commit 993e60f8de
No known key found for this signature in database
11 changed files with 521 additions and 380 deletions

773
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,7 @@ serde_json = { workspace = true }
parse_duration = "2.1.1"
async-trait = { workspace = true }
itertools = { workspace = true }
shellexpand = "2"
shellexpand = "3"
sqlx = { workspace = true, features = ["sqlite"] }
minspan = "0.1.1"
regex = "1.5.4"

View File

@ -129,7 +129,7 @@ impl<'a> From<&'a [u8]> for LineType<'a> {
fn try_parse_line_as_timestamp(line: &str) -> Option<DateTime<Utc>> {
let seconds = line.strip_prefix('#')?.parse().ok()?;
let time = NaiveDateTime::from_timestamp(seconds, 0);
let time = NaiveDateTime::from_timestamp_opt(seconds, 0)?;
Some(DateTime::from_utc(time, Utc))
}

View File

@ -99,7 +99,7 @@ impl Importer for Fish {
} else if let Some(t) = s.strip_prefix(" when: ") {
// if t is not an int, just ignore this line
if let Ok(t) = t.parse::<i64>() {
time = Some(Utc.timestamp(t, 0));
time = Utc.timestamp_opt(t, 0).single();
}
} else {
// ... ignore paths lines

View File

@ -30,8 +30,14 @@ impl From<HistDbEntry> for History {
fn from(histdb_item: HistDbEntry) -> Self {
let ts_secs = histdb_item.start_timestamp / 1000;
let ts_ns = (histdb_item.start_timestamp % 1000) * 1_000_000;
let ts = NaiveDateTime::from_timestamp_opt(ts_secs, ts_ns as u32)
.expect("invalid timestamp")
.and_local_timezone(Utc)
.single()
.expect("failed timezone conversion");
History::new(
DateTime::from_utc(NaiveDateTime::from_timestamp(ts_secs, ts_ns as u32), Utc),
ts,
String::from_utf8(histdb_item.command_line).unwrap(),
String::from_utf8(histdb_item.cwd).unwrap(),
histdb_item.exit_status,

View File

@ -111,14 +111,20 @@ impl Importer for Resh {
let timestamp = {
let secs = entry.realtime_before.floor() as i64;
let nanosecs = (entry.realtime_before.fract() * 1_000_000_000_f64).round() as u32;
Utc.timestamp(secs, nanosecs)
Utc.timestamp_opt(secs, nanosecs)
.single()
.expect("invalid timestamp")
};
#[allow(clippy::cast_possible_truncation)]
#[allow(clippy::cast_sign_loss)]
let duration = {
let secs = entry.realtime_after.floor() as i64;
let nanosecs = (entry.realtime_after.fract() * 1_000_000_000_f64).round() as u32;
let difference = Utc.timestamp(secs, nanosecs) - timestamp;
let difference = Utc
.timestamp_opt(secs, nanosecs)
.single()
.expect("invalid timestamp")
- timestamp;
difference.num_nanoseconds().unwrap_or(0)
};

View File

@ -106,7 +106,10 @@ fn parse_extended(line: &str, counter: i64) -> History {
.unwrap_or_else(|_| chrono::Utc::now().timestamp());
let offset = chrono::Duration::milliseconds(counter);
let time = Utc.timestamp(time, 0);
let time = Utc
.timestamp_opt(time, 0)
.single()
.expect("invalid timestamp for history item");
let time = time + offset;
let duration = duration.parse::<i64>().map_or(-1, |t| t * 1_000_000_000);
@ -140,25 +143,37 @@ mod test {
assert_eq!(parsed.command, "cargo install atuin");
assert_eq!(parsed.duration, 0);
assert_eq!(parsed.timestamp, Utc.timestamp(1_613_322_469, 0));
assert_eq!(
parsed.timestamp,
Utc.timestamp_opt(1_613_322_469, 0).unwrap()
);
let parsed = parse_extended("1613322469:10;cargo install atuin;cargo update", 0);
assert_eq!(parsed.command, "cargo install atuin;cargo update");
assert_eq!(parsed.duration, 10_000_000_000);
assert_eq!(parsed.timestamp, Utc.timestamp(1_613_322_469, 0));
assert_eq!(
parsed.timestamp,
Utc.timestamp_opt(1_613_322_469, 0).unwrap()
);
let parsed = parse_extended("1613322469:10;cargo :b̷i̶t̴r̵o̴t̴ ̵i̷s̴ ̷r̶e̵a̸l̷", 0);
assert_eq!(parsed.command, "cargo :b̷i̶t̴r̵o̴t̴ ̵i̷s̴ ̷r̶e̵a̸l̷");
assert_eq!(parsed.duration, 10_000_000_000);
assert_eq!(parsed.timestamp, Utc.timestamp(1_613_322_469, 0));
assert_eq!(
parsed.timestamp,
Utc.timestamp_opt(1_613_322_469, 0).unwrap()
);
let parsed = parse_extended("1613322469:10;cargo install \\n atuin\n", 0);
assert_eq!(parsed.command, "cargo install \\n atuin");
assert_eq!(parsed.duration, 10_000_000_000);
assert_eq!(parsed.timestamp, Utc.timestamp(1_613_322_469, 0));
assert_eq!(
parsed.timestamp,
Utc.timestamp_opt(1_613_322_469, 0).unwrap()
);
}
#[tokio::test]

View File

@ -202,7 +202,7 @@ impl Settings {
Ok(time.with_timezone(&Utc))
}
None => Ok(Utc.ymd(1970, 1, 1).and_hms(0, 0, 0)),
None => Ok(Utc.timestamp_nanos(0)),
}
}

View File

@ -49,12 +49,12 @@ async fn sync_download(
let mut local_count = initial_local;
let mut last_sync = if force {
Utc.timestamp_millis(0)
Utc.timestamp_nanos(0)
} else {
Settings::last_sync()?
};
let mut last_timestamp = Utc.timestamp_millis(0);
let mut last_timestamp = Utc.timestamp_nanos(0);
let host = if force { Some(String::from("")) } else { None };
@ -85,7 +85,7 @@ async fn sync_download(
// be "lost" between syncs. In this case we need to rewind the sync
// timestamps
if page_last == last_timestamp {
last_timestamp = Utc.timestamp_millis(0);
last_timestamp = Utc.timestamp_nanos(0);
last_sync -= chrono::Duration::hours(1);
} else {
last_timestamp = page_last;

View File

@ -107,9 +107,9 @@ impl Database for Postgres {
#[instrument(skip_all)]
async fn get_session_user(&self, token: &str) -> Result<User> {
sqlx::query_as::<_, User>(
"select users.id, users.username, users.email, users.password from users
inner join sessions
on users.id = sessions.user_id
"select users.id, users.username, users.email, users.password from users
inner join sessions
on users.id = sessions.user_id
and sessions.token = $1",
)
.bind(token)
@ -171,7 +171,7 @@ impl Database for Postgres {
// edge case.
let res = sqlx::query(
"select client_id from history
"select client_id from history
where user_id = $1
and deleted_at is not null",
)
@ -212,7 +212,10 @@ impl Database for Postgres {
// Count the history for a given year
#[instrument(skip_all)]
async fn count_history_year(&self, user: &User, year: i32) -> Result<i64> {
let start = chrono::Utc.ymd(year, 1, 1).and_hms_nano(0, 0, 0, 0);
let start = chrono::Utc
.with_ymd_and_hms(year, 1, 1, 0, 0, 0)
.single()
.expect("invalid year");
let end = start + RelativeDuration::years(1);
let res = self
@ -224,42 +227,25 @@ impl Database for Postgres {
// Count the history for a given month
#[instrument(skip_all)]
async fn count_history_month(&self, user: &User, month: chrono::NaiveDate) -> Result<i64> {
let start = chrono::Utc
.ymd(month.year(), month.month(), 1)
.and_hms_nano(0, 0, 0, 0);
// ofc...
let end = if month.month() < 12 {
chrono::Utc
.ymd(month.year(), month.month() + 1, 1)
.and_hms_nano(0, 0, 0, 0)
} else {
chrono::Utc
.ymd(month.year() + 1, 1, 1)
.and_hms_nano(0, 0, 0, 0)
};
let start = month
.with_day(1)
.unwrap() // should be unconditionally safe
.and_time(chrono::NaiveTime::from_hms_opt(0, 0, 0).unwrap()); // should be unconditionally safe also
let end = start.checked_add_months(chrono::Months::new(1)).unwrap(); // None in the case of overflow, which is kinda impossible here
debug!("start: {}, end: {}", start, end);
let res = self
.count_history_range(user, start.naive_utc(), end.naive_utc())
.await?;
let res = self.count_history_range(user, start, end).await?;
Ok(res)
}
// Count the history for a given day
#[instrument(skip_all)]
async fn count_history_day(&self, user: &User, day: chrono::NaiveDate) -> Result<i64> {
let start = chrono::Utc
.ymd(day.year(), day.month(), day.day())
.and_hms_nano(0, 0, 0, 0);
let end = chrono::Utc
.ymd(day.year(), day.month(), day.day() + 1)
.and_hms_nano(0, 0, 0, 0);
let start = day.and_time(chrono::NaiveTime::from_hms_opt(0, 0, 0).unwrap());
let end = start.checked_add_days(chrono::Days::new(1)).unwrap();
let res = self
.count_history_range(user, start.naive_utc(), end.naive_utc())
.await?;
let res = self.count_history_range(user, start, end).await?;
Ok(res)
}
@ -272,7 +258,7 @@ impl Database for Postgres {
host: &str,
) -> Result<Vec<History>> {
let res = sqlx::query_as::<_, History>(
"select id, client_id, user_id, hostname, timestamp, data, created_at from history
"select id, client_id, user_id, hostname, timestamp, data, created_at from history
where user_id = $1
and hostname != $2
and created_at >= $3
@ -317,7 +303,7 @@ impl Database for Postgres {
sqlx::query(
"insert into history
(client_id, user_id, hostname, timestamp, data)
(client_id, user_id, hostname, timestamp, data)
values ($1, $2, $3, $4, $5)
on conflict do nothing
",
@ -385,7 +371,7 @@ impl Database for Postgres {
#[instrument(skip_all)]
async fn oldest_history(&self, user: &User) -> Result<History> {
let res = sqlx::query_as::<_, History>(
"select id, client_id, user_id, hostname, timestamp, data, created_at from history
"select id, client_id, user_id, hostname, timestamp, data, created_at from history
where user_id = $1
order by timestamp asc
limit 1",
@ -443,7 +429,7 @@ impl Database for Postgres {
let count = self
.count_history_month(
user,
chrono::Utc.ymd(year as i32, month, 1).naive_utc(),
chrono::NaiveDate::from_ymd_opt(year as i32, month as u32, 1).unwrap(),
)
.await?;
@ -466,9 +452,8 @@ impl Database for Postgres {
let count = self
.count_history_day(
user,
chrono::Utc
.ymd(year as i32, month as u32, day as u32)
.naive_utc(),
chrono::NaiveDate::from_ymd_opt(year as i32, month as u32, day as u32)
.unwrap(),
)
.await?;

View File

@ -1,6 +1,6 @@
use std::collections::{HashMap, HashSet};
use chrono::{prelude::*, Duration};
use chrono::{prelude::*, Duration, DurationRound};
use clap::Parser;
use crossterm::style::{Color, ResetColor, SetAttribute, SetForegroundColor};
use eyre::{bail, Result};
@ -83,19 +83,19 @@ impl Cmd {
let history = if words.as_str() == "all" {
db.list(FilterMode::Global, &context, None, false).await?
} else if words.trim() == "today" {
let start = Local::now().date().and_hms(0, 0, 0);
let start = Local::now().duration_trunc(Duration::days(1)).unwrap();
let end = start + Duration::days(1);
db.range(start.into(), end.into()).await?
} else if words.trim() == "month" {
let end = Local::now().date().and_hms(0, 0, 0);
let end = Local::now().duration_trunc(Duration::days(1)).unwrap();
let start = end - Duration::days(31);
db.range(start.into(), end.into()).await?
} else if words.trim() == "week" {
let end = Local::now().date().and_hms(0, 0, 0);
let end = Local::now().duration_trunc(Duration::days(1)).unwrap();
let start = end - Duration::days(7);
db.range(start.into(), end.into()).await?
} else if words.trim() == "year" {
let end = Local::now().date().and_hms(0, 0, 0);
let end = Local::now().duration_trunc(Duration::days(1)).unwrap();
let start = end - Duration::days(365);
db.range(start.into(), end.into()).await?
} else {