Skip to content

Commit 2abad3a

Browse files
committed
[actor #189] methods to get an actor signature at the current time
1 parent b58134b commit 2abad3a

File tree

8 files changed

+124
-43
lines changed

8 files changed

+124
-43
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

git-actor/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ serde1 = ["serde", "bstr/serde1"]
1818
all-features = true
1919

2020
[dependencies]
21+
git-features = { version = "^0.16.0", path = "../git-features", features = ["time"] }
2122
quick-error = "2.0.0"
2223
btoi = "0.4.2"
2324
bstr = { version = "0.2.13", default-features = false, features = ["std"]}

git-actor/src/signature/mod.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,75 @@ mod write {
9999
}
100100
}
101101

102+
mod init {
103+
use crate::{Signature, Time};
104+
use bstr::BString;
105+
106+
impl Signature {
107+
/// Return an actor identified `name` and `email` at the current local time, that is a time with a timezone offset from
108+
/// UTC based on the hosts configuration.
109+
pub fn now_local(
110+
name: impl Into<BString>,
111+
email: impl Into<BString>,
112+
) -> Result<Self, git_features::time::tz::Error> {
113+
let offset = git_features::time::tz::current_utc_offset()?;
114+
Ok(Signature {
115+
name: name.into(),
116+
email: email.into(),
117+
time: Time {
118+
time: std::time::SystemTime::now()
119+
.duration_since(std::time::UNIX_EPOCH)
120+
.expect("the system time doesn't run backwards that much")
121+
.as_secs() as u32,
122+
offset,
123+
sign: offset.into(),
124+
},
125+
})
126+
}
127+
128+
/// Return an actor identified `name` and `email` at the current local time, or UTC time if the current time zone could
129+
/// not be obtained.
130+
pub fn now_local_or_utc(name: impl Into<BString>, email: impl Into<BString>) -> Self {
131+
let offset = git_features::time::tz::current_utc_offset().unwrap_or(0);
132+
Signature {
133+
name: name.into(),
134+
email: email.into(),
135+
time: Time {
136+
time: std::time::SystemTime::now()
137+
.duration_since(std::time::UNIX_EPOCH)
138+
.expect("the system time doesn't run backwards that much")
139+
.as_secs() as u32,
140+
offset,
141+
sign: offset.into(),
142+
},
143+
}
144+
}
145+
146+
/// Return an actor identified by `name` and `email` at the current time in UTC.
147+
///
148+
/// This would be most useful for bot users, otherwise the [`now_local()`][Signature::now_local()] method should be preferred.
149+
pub fn now_utc(name: impl Into<BString>, email: impl Into<BString>) -> Self {
150+
let utc_offset = 0;
151+
Signature {
152+
name: name.into(),
153+
email: email.into(),
154+
time: Time {
155+
time: seconds_since_epoch(),
156+
offset: utc_offset,
157+
sign: utc_offset.into(),
158+
},
159+
}
160+
}
161+
}
162+
163+
fn seconds_since_epoch() -> u32 {
164+
std::time::SystemTime::now()
165+
.duration_since(std::time::UNIX_EPOCH)
166+
.expect("the system time doesn't run backwards that much")
167+
.as_secs() as u32
168+
}
169+
}
170+
102171
///
103172
mod decode;
104173
pub use decode::decode;

git-actor/src/time.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@ use std::io;
22

33
use crate::{Sign, Time, SPACE};
44

5+
impl From<i32> for Sign {
6+
fn from(v: i32) -> Self {
7+
if v < 0 {
8+
Sign::Minus
9+
} else {
10+
Sign::Plus
11+
}
12+
}
13+
}
14+
515
impl Time {
616
/// Serialize this instance to `out` in a format suitable for use in header fields of serialized git commits or tags.
717
pub fn write_to(&self, mut out: impl io::Write) -> io::Result<()> {

git-actor/tests/actor.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use std::path::PathBuf;
22

3-
mod signature;
4-
53
pub use git_testtools::hex_to_id;
64

75
pub fn fixture(path: &str) -> PathBuf {
86
PathBuf::from("tests/fixtures").join(path)
97
}
8+
9+
mod signature;
10+
mod time;

git-actor/tests/signature/mod.rs

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,3 @@
1-
mod time {
2-
use bstr::ByteSlice;
3-
use git_actor::{Sign, Time};
4-
5-
#[test]
6-
fn write_to() -> Result<(), Box<dyn std::error::Error>> {
7-
for (time, expected) in &[
8-
(
9-
Time {
10-
time: 500,
11-
offset: 9000,
12-
sign: Sign::Plus,
13-
},
14-
"500 +0230",
15-
),
16-
(
17-
Time {
18-
time: 189009009,
19-
offset: 36000,
20-
sign: Sign::Minus,
21-
},
22-
"189009009 -1000",
23-
),
24-
(
25-
Time {
26-
time: 0,
27-
offset: 0,
28-
sign: Sign::Minus,
29-
},
30-
"0 -0000",
31-
),
32-
] {
33-
let mut output = Vec::new();
34-
time.write_to(&mut output)?;
35-
assert_eq!(output.as_bstr(), expected);
36-
}
37-
Ok(())
38-
}
39-
}
40-
411
mod write_to {
422
mod invalid {
433
use git_actor::{Sign, Signature, Time};

git-actor/tests/time/mod.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use bstr::ByteSlice;
2+
use git_actor::{Sign, Time};
3+
4+
#[test]
5+
fn write_to() -> Result<(), Box<dyn std::error::Error>> {
6+
for (time, expected) in &[
7+
(
8+
Time {
9+
time: 500,
10+
offset: 9000,
11+
sign: Sign::Plus,
12+
},
13+
"500 +0230",
14+
),
15+
(
16+
Time {
17+
time: 189009009,
18+
offset: 36000,
19+
sign: Sign::Minus,
20+
},
21+
"189009009 -1000",
22+
),
23+
(
24+
Time {
25+
time: 0,
26+
offset: 0,
27+
sign: Sign::Minus,
28+
},
29+
"0 -0000",
30+
),
31+
] {
32+
let mut output = Vec::new();
33+
time.write_to(&mut output)?;
34+
assert_eq!(output.as_bstr(), expected);
35+
}
36+
Ok(())
37+
}

git-features/src/time.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ pub mod tz {
2525
/// Note that there may be various legitimate reasons for failure, which should be accounted for.
2626
pub fn current_utc_offset() -> Result<UTCOffsetInSeconds, Error> {
2727
// TODO: make this work without cfg(unsound_local_offset), see
28-
// https://github.com/time-rs/time/issues/293#issuecomment-909158529
28+
// https://github.com/time-rs/time/issues/293#issuecomment-909158529
29+
// TODO: get a function to return the current time as well to avoid double-lookups
30+
// (to get the offset, the current time is needed)
2931
time::UtcOffset::current_local_offset()
3032
.map(|ofs| ofs.whole_seconds())
3133
.map_err(|_| Error)

0 commit comments

Comments
 (0)