Add fs::MTime newtype to encourage != instead of > (#20830)

See ["mtime comparison considered
harmful"](https://apenwarr.ca/log/20181113) for details of why
comparators other than equality/inequality should not be used with
mtime.

Release Notes:

- N/A
This commit is contained in:
Michael Sloan 2024-11-21 19:21:18 -07:00 committed by GitHub
parent 477c6e6833
commit 14ea4621ab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 155 additions and 112 deletions

View file

@ -1,8 +1,8 @@
use anyhow::Result;
use db::sqlez::bindable::{Bind, Column, StaticColumnCount};
use db::sqlez::statement::Statement;
use fs::MTime;
use std::path::PathBuf;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use db::sqlez_macros::sql;
use db::{define_connection, query};
@ -14,7 +14,7 @@ pub(crate) struct SerializedEditor {
pub(crate) abs_path: Option<PathBuf>,
pub(crate) contents: Option<String>,
pub(crate) language: Option<String>,
pub(crate) mtime: Option<SystemTime>,
pub(crate) mtime: Option<MTime>,
}
impl StaticColumnCount for SerializedEditor {
@ -29,16 +29,13 @@ impl Bind for SerializedEditor {
let start_index = statement.bind(&self.contents, start_index)?;
let start_index = statement.bind(&self.language, start_index)?;
let mtime = self.mtime.and_then(|mtime| {
mtime
.duration_since(UNIX_EPOCH)
.ok()
.map(|duration| (duration.as_secs() as i64, duration.subsec_nanos() as i32))
});
let start_index = match mtime {
let start_index = match self
.mtime
.and_then(|mtime| mtime.to_seconds_and_nanos_for_persistence())
{
Some((seconds, nanos)) => {
let start_index = statement.bind(&seconds, start_index)?;
statement.bind(&nanos, start_index)?
let start_index = statement.bind(&(seconds as i64), start_index)?;
statement.bind(&(nanos as i32), start_index)?
}
None => {
let start_index = statement.bind::<Option<i64>>(&None, start_index)?;
@ -64,7 +61,7 @@ impl Column for SerializedEditor {
let mtime = mtime_seconds
.zip(mtime_nanos)
.map(|(seconds, nanos)| UNIX_EPOCH + Duration::new(seconds as u64, nanos as u32));
.map(|(seconds, nanos)| MTime::from_seconds_and_nanos(seconds as u64, nanos as u32));
let editor = Self {
abs_path,
@ -280,12 +277,11 @@ mod tests {
assert_eq!(have, serialized_editor);
// Storing and retrieving mtime
let now = SystemTime::now();
let serialized_editor = SerializedEditor {
abs_path: None,
contents: None,
language: None,
mtime: Some(now),
mtime: Some(MTime::from_seconds_and_nanos(100, 42)),
};
DB.save_serialized_editor(1234, workspace_id, serialized_editor.clone())