Skip to content

Commit a951019

Browse files
committed
Switch from time crate to jiff
1 parent 9a7833e commit a951019

19 files changed

Lines changed: 147 additions & 132 deletions

Cargo.lock

Lines changed: 57 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,17 @@ strum_macros = "0.26"
6161
tempfile = "3"
6262
thiserror = "2.0"
6363
thousands = "0.2.0"
64-
time = { version = "0.3.47", features = [
65-
"local-offset",
66-
"macros",
67-
"serde",
68-
"serde-human-readable",
69-
] }
7064
tokio = { version = "1.43", features = ["full", "test-util", "tracing"] }
7165
tracing = "0.1"
7266
tracing-appender = "0.2"
7367
unix_mode = "0.1"
7468
url = "2.2.2"
7569
whoami = "1.5.2"
7670

71+
[dependencies.jiff]
72+
version = "0.2"
73+
features = ["serde"]
74+
7775
[target.'cfg(unix)'.dependencies]
7876
uzers = "0.11"
7977
nix = { version = "0.28", features = ["fs", "user"] }

src/band.rs

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ use std::sync::Arc;
2626

2727
use crate::transport::Transport;
2828
use itertools::Itertools;
29+
use jiff::Timestamp;
2930
use serde::{Deserialize, Serialize};
30-
use time::OffsetDateTime;
3131
use tracing::{debug, trace, warn};
3232

3333
use crate::jsonio::{read_json, write_json};
@@ -83,7 +83,7 @@ pub struct Band {
8383
#[derive(Debug, Clone, Serialize, Deserialize)]
8484
struct Head {
8585
/// Seconds since the Unix epoch when writing of this band began.
86-
start_time: i64,
86+
start_time: i64, // TODO: Maybe a timestamp with custom serializer
8787

8888
/// Semver string for the minimum Conserve version to read this band
8989
/// correctly.
@@ -99,7 +99,7 @@ struct Head {
9999
#[derive(Debug, Serialize, Deserialize)]
100100
struct Tail {
101101
/// Seconds since the Unix epoch when the band was closed.
102-
end_time: i64,
102+
end_time: i64, // TODO: Maybe a timestamp with custom serializer
103103

104104
/// Number of index hunks in this band, to enable validation that none are missing.
105105
///
@@ -113,10 +113,10 @@ pub struct Info {
113113
pub is_closed: bool,
114114

115115
/// Time Conserve started writing this band.
116-
pub start_time: OffsetDateTime,
116+
pub start_time: Timestamp,
117117

118118
/// Time this band was completed, if it is complete.
119-
pub end_time: Option<OffsetDateTime>,
119+
pub end_time: Option<Timestamp>,
120120

121121
/// Number of hunks present in the index, if that is known.
122122
pub index_hunk_count: Option<u64>,
@@ -153,7 +153,7 @@ impl Band {
153153
Some("23.2.0".to_owned())
154154
};
155155
let head = Head {
156-
start_time: OffsetDateTime::now_utc().unix_timestamp(),
156+
start_time: Timestamp::now().as_second(),
157157
band_format_version,
158158
format_flags: format_flags.into(),
159159
};
@@ -171,7 +171,7 @@ impl Band {
171171
&self.transport,
172172
BAND_TAIL_FILENAME,
173173
&Tail {
174-
end_time: OffsetDateTime::now_utc().unix_timestamp(),
174+
end_time: Timestamp::now().as_second(),
175175
index_hunk_count: Some(index_hunk_count),
176176
},
177177
)
@@ -267,18 +267,14 @@ impl Band {
267267
pub async fn get_info(&self) -> Result<Info> {
268268
let tail_option: Option<Tail> = read_json(&self.transport, BAND_TAIL_FILENAME).await?;
269269
let start_time =
270-
OffsetDateTime::from_unix_timestamp(self.head.start_time).map_err(|_| {
271-
Error::InvalidMetadata {
272-
details: format!("Invalid band start timestamp {:?}", self.head.start_time),
273-
}
270+
Timestamp::from_second(self.head.start_time).map_err(|_| Error::InvalidMetadata {
271+
details: format!("Invalid band start timestamp {:?}", self.head.start_time),
274272
})?;
275273
let end_time = tail_option
276274
.as_ref()
277275
.map(|tail| {
278-
OffsetDateTime::from_unix_timestamp(tail.end_time).map_err(|_| {
279-
Error::InvalidMetadata {
280-
details: format!("Invalid band end timestamp {:?}", tail.end_time),
281-
}
276+
Timestamp::from_second(tail.end_time).map_err(|_| Error::InvalidMetadata {
277+
details: format!("Invalid band end timestamp {:?}", tail.end_time),
282278
})
283279
})
284280
.transpose()?;
@@ -312,7 +308,6 @@ impl Band {
312308
mod tests {
313309
use std::fs;
314310
use std::str::FromStr;
315-
use std::time::Duration;
316311

317312
use serde_json::json;
318313

@@ -355,7 +350,7 @@ mod tests {
355350
let dur = info.end_time.expect("info has an end_time") - info.start_time;
356351
// Test should have taken (much) less than 5s between starting and finishing
357352
// the band. (It might fail if you set a breakpoint right there.)
358-
assert!(dur < Duration::from_secs(5));
353+
assert!(dur.get_seconds() < 5);
359354
}
360355

361356
#[tokio::test]

src/bin/conserve.rs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,19 @@ use std::cell::RefCell;
1717
use std::fs::{File, OpenOptions};
1818
use std::io::{self, BufWriter, Write};
1919
use std::path::{Path, PathBuf};
20-
use std::sync::{Arc, RwLock};
20+
use std::sync::Arc;
2121
use std::time::Instant;
2222

2323
use clap::builder::{Styles, styling};
2424
use clap::{Parser, Subcommand};
2525
use conserve::change::Change;
26-
use time::UtcOffset;
2726
#[allow(unused_imports)]
2827
use tracing::{Level, debug, error, info, trace, warn};
2928

3029
use crate::transport::Transport;
3130
use conserve::termui::{TermUiMonitor, TraceTimeStyle, enable_tracing};
3231
use conserve::*;
3332

34-
/// Local timezone offset, calculated once at startup, to avoid issues about
35-
/// looking at the environment once multiple threads are running.
36-
static LOCAL_OFFSET: RwLock<UtcOffset> = RwLock::new(UtcOffset::UTC);
37-
3833
#[mutants::skip] // only visual effects, not worth testing
3934
fn clap_styles() -> Styles {
4035
styling::Styles::styled()
@@ -630,16 +625,11 @@ impl Command {
630625
sizes,
631626
utc,
632627
} => {
633-
let timezone = if *utc {
634-
None
635-
} else {
636-
Some(*LOCAL_OFFSET.read().unwrap())
637-
};
638628
let archive = Archive::open(Transport::new(archive).await?).await?;
639629
let options = ShowVersionsOptions {
640630
newest_first: *newest,
641631
tree_size: *sizes,
642-
timezone,
632+
utc: *utc,
643633
start_time: !*short,
644634
backup_duration: !*short,
645635
};
@@ -716,10 +706,6 @@ fn make_change_callback(
716706
}
717707

718708
fn main() -> Result<ExitCode> {
719-
// Before anything else, get the local time offset, to avoid `time-rs`
720-
// problems with loading it when threads are running.
721-
*LOCAL_OFFSET.write().unwrap() =
722-
UtcOffset::current_local_offset().expect("get local time offset");
723709
let args = Args::parse();
724710
let start_time = Instant::now();
725711
let console_level = if args.debug {

src/change.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
1616
use std::fmt;
1717

18+
use jiff::Timestamp;
1819
use serde::Serialize;
19-
use time::OffsetDateTime;
2020

2121
use crate::{Apath, EntryTrait, Kind, Owner, Result, UnixMode};
2222

@@ -138,7 +138,7 @@ pub struct EntryMetadata {
138138
// TODO: Eventually unify with EntryValue or Entry?
139139
#[serde(flatten)]
140140
pub kind: KindMetadata,
141-
pub mtime: OffsetDateTime,
141+
pub mtime: Timestamp,
142142
#[serde(flatten)]
143143
pub owner: Owner,
144144
pub unix_mode: UnixMode,

src/entry.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
1717
use std::fmt::Debug;
1818

19+
use jiff::Timestamp;
1920
use serde::Serialize;
20-
use time::OffsetDateTime;
2121

2222
use crate::*;
2323

@@ -29,7 +29,7 @@ use crate::*;
2929
pub trait EntryTrait: Debug {
3030
fn apath(&self) -> &Apath;
3131
fn kind(&self) -> Kind;
32-
fn mtime(&self) -> OffsetDateTime;
32+
fn mtime(&self) -> Timestamp;
3333
fn size(&self) -> Option<u64>;
3434
fn symlink_target(&self) -> Option<&str>;
3535
fn unix_mode(&self) -> UnixMode;

src/index/entry.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1212
// GNU General Public License for more details.
1313

14+
use jiff::Timestamp;
1415
use serde_json::json;
15-
use time::OffsetDateTime;
1616

1717
use crate::apath::Apath;
1818
use crate::entry::EntryTrait;
1919
use crate::kind::Kind;
2020
use crate::owner::Owner;
2121
use crate::unix_mode::UnixMode;
22-
use crate::unix_time::FromUnixAndNanos;
2322
use crate::{blockdir, source};
2423

2524
/// Description of one archived file.
@@ -83,8 +82,9 @@ impl EntryTrait for IndexEntry {
8382
}
8483

8584
#[inline]
86-
fn mtime(&self) -> OffsetDateTime {
87-
OffsetDateTime::from_unix_seconds_and_nanos(self.mtime, self.mtime_nanos)
85+
fn mtime(&self) -> Timestamp {
86+
Timestamp::new(self.mtime, self.mtime_nanos.try_into().unwrap())
87+
.expect("Failed to convert mtime and mtime_nanos to Timestamp")
8888
}
8989

9090
/// Size of the file, if it is a file. None for directories and symlinks.
@@ -142,8 +142,8 @@ impl IndexEntry {
142142
kind: source.kind(),
143143
addrs: Vec::new(),
144144
target: source.symlink_target().map(|t| t.to_owned()),
145-
mtime: mtime.unix_timestamp(),
146-
mtime_nanos: mtime.nanosecond(),
145+
mtime: mtime.as_second(),
146+
mtime_nanos: mtime.subsec_nanosecond().try_into().unwrap(),
147147
unix_mode: source.unix_mode(),
148148
owner: source.owner().to_owned(),
149149
}

src/restore.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::sync::Arc;
2121
use filetime::set_file_handle_times;
2222
#[cfg(unix)]
2323
use filetime::set_symlink_file_times;
24-
use time::OffsetDateTime;
24+
use jiff::Timestamp;
2525
use tracing::{instrument, trace};
2626

2727
use crate::blockdir::BlockDir;
@@ -176,7 +176,7 @@ fn restore_dir(apath: &Apath, restore_path: &Path, options: &RestoreOptions) ->
176176
struct DirDeferral {
177177
path: PathBuf,
178178
unix_mode: UnixMode,
179-
mtime: OffsetDateTime,
179+
mtime: Timestamp,
180180
owner: Owner,
181181
}
182182

@@ -200,7 +200,7 @@ fn apply_deferrals(deferrals: &[DirDeferral], monitor: Arc<dyn Monitor>) -> Resu
200200
source,
201201
});
202202
}
203-
if let Err(source) = filetime::set_file_mtime(path, (*mtime).to_file_time()) {
203+
if let Err(source) = filetime::set_file_mtime(path, mtime.to_file_time()) {
204204
monitor.error(Error::RestoreModificationTime {
205205
path: path.clone(),
206206
source,

0 commit comments

Comments
 (0)