Skip to content

Commit 206f392

Browse files
committed
parse() returns Result.
1 parent 5c3b733 commit 206f392

File tree

4 files changed

+38
-39
lines changed

4 files changed

+38
-39
lines changed

git-date/src/parse.rs

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use time::{Date, OffsetDateTime};
1010
pub enum Error {
1111
#[error("Date string can not be parsed")]
1212
InvalidDateString,
13+
1314
#[error("Timezone offset can not be parsed")]
1415
InvalidTzOffset,
1516
#[error("Relative period can not be parsed")]
@@ -19,70 +20,68 @@ pub enum Error {
1920
}
2021

2122
#[allow(missing_docs)]
22-
pub fn parse(input: &str) -> Option<Time> {
23+
pub fn parse(input: &str) -> Result<Time, Error> {
2324
// TODO: actual implementation, this is just to not constantly fail
2425
if input == "1979-02-26 18:30:00" {
25-
Some(Time::new(42, 1800))
26+
Ok(Time::new(42, 1800))
2627
} else {
2728
return if let Ok(val) = Date::parse(input, SHORT) {
2829
let val = val.with_hms(0, 0, 0).expect("date is in range").assume_utc();
29-
Some(Time::new(val.unix_timestamp() as u32, val.offset().whole_seconds()))
30+
Ok(Time::new(val.unix_timestamp() as u32, val.offset().whole_seconds()))
3031
} else if let Ok(val) = OffsetDateTime::parse(input, RFC2822) {
31-
Some(Time::new(val.unix_timestamp() as u32, val.offset().whole_seconds()))
32+
Ok(Time::new(val.unix_timestamp() as u32, val.offset().whole_seconds()))
3233
} else if let Ok(val) = OffsetDateTime::parse(input, ISO8601) {
33-
Some(Time::new(val.unix_timestamp() as u32, val.offset().whole_seconds()))
34+
Ok(Time::new(val.unix_timestamp() as u32, val.offset().whole_seconds()))
3435
} else if let Ok(val) = OffsetDateTime::parse(input, ISO8601_STRICT) {
35-
Some(Time::new(val.unix_timestamp() as u32, val.offset().whole_seconds()))
36+
Ok(Time::new(val.unix_timestamp() as u32, val.offset().whole_seconds()))
3637
} else if let Ok(val) = OffsetDateTime::parse(input, DEFAULT) {
37-
Some(Time::new(val.unix_timestamp() as u32, val.offset().whole_seconds()))
38+
Ok(Time::new(val.unix_timestamp() as u32, val.offset().whole_seconds()))
3839
} else if let Ok(val) = u32::from_str(input) {
3940
// Format::Unix
40-
Some(Time::new(val, 0))
41-
} else if let Ok(val) = parse_raw(input) {
41+
Ok(Time::new(val, 0))
42+
} else if let Some(val) = parse_raw(input) {
4243
// Format::Raw
43-
Some(val)
44-
} else if let Ok(val) = relative::parse(input) {
45-
Some(Time::new(val.unix_timestamp() as u32, val.offset().whole_seconds()))
44+
Ok(val)
45+
} else if let Some(val) = relative::parse(input) {
46+
Ok(Time::new(val.unix_timestamp() as u32, val.offset().whole_seconds()))
4647
} else {
47-
None
48+
Err(Error::InvalidDateString)
4849
};
4950
}
5051
}
5152

52-
fn parse_raw(input: &str) -> Result<Time, Error> {
53+
fn parse_raw(input: &str) -> Option<Time> {
5354
let mut split = input.split_whitespace();
54-
let seconds_since_unix_epoch: u32 = split.next().ok_or(Error::InvalidDateString)?.parse()?;
55-
let offset = split.next().ok_or(Error::InvalidDateString)?;
55+
let seconds_since_unix_epoch: u32 = split.next()?.parse().ok()?;
56+
let offset = split.next()?;
5657
if offset.len() != 5 {
57-
return Err(Error::InvalidTzOffset);
58+
return None;
5859
}
5960
let sign = if &offset[..1] == "-" { Sign::Plus } else { Sign::Minus };
60-
let hours: i32 = offset[1..3].parse()?;
61-
let minutes: i32 = offset[3..5].parse()?;
61+
let hours: i32 = offset[1..3].parse().ok()?;
62+
let minutes: i32 = offset[3..5].parse().ok()?;
6263
let offset_in_seconds = hours * 3600 + minutes * 60;
6364
let time = Time {
6465
seconds_since_unix_epoch,
6566
offset_in_seconds,
6667
sign,
6768
};
68-
Ok(time)
69+
Some(time)
6970
}
7071

7172
mod relative {
7273
use crate::parse::Error;
7374
use std::str::FromStr;
7475
use time::{Duration, OffsetDateTime};
7576

76-
pub(crate) fn parse(input: &str) -> Result<OffsetDateTime, Error> {
77+
pub(crate) fn parse(input: &str) -> Option<OffsetDateTime> {
7778
let mut split = input.split_whitespace();
78-
let multiplier = i64::from_str(split.next().ok_or(Error::InvalidDateString)?)?;
79-
let period = period_to_seconds(split.next().ok_or(Error::InvalidDateString)?)?;
80-
if split.next().ok_or(Error::InvalidDateString)? != "ago" {
81-
return Err(Error::InvalidDateString);
79+
let multiplier = i64::from_str(split.next()?).ok()?;
80+
let period = period_to_seconds(split.next()?).ok()?;
81+
if split.next()? != "ago" {
82+
return None;
8283
}
83-
Ok(OffsetDateTime::now_utc()
84-
.checked_sub(Duration::seconds(multiplier * period))
85-
.ok_or(Error::InvalidDateString)?)
84+
OffsetDateTime::now_utc().checked_sub(Duration::seconds(multiplier * period))
8685
}
8786

8887
fn period_to_seconds(period: &str) -> Result<i64, Error> {

git-date/tests/time/parse.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ fn baseline() {
3030
for (pattern, (exit_code, output)) in BASELINE.iter() {
3131
let res = git_date::parse(pattern.to_str().expect("valid pattern"));
3232
assert_eq!(
33-
res.is_some(),
33+
res.is_ok(),
3434
*exit_code == 0,
3535
"{pattern:?} disagrees with baseline: {res:?}"
3636
);
3737
if *exit_code == 0 {
3838
let actual = res.unwrap().seconds_since_unix_epoch;
3939
let expected = u32::from_str(output.to_str().expect("valid utf")).expect("valid epoch value");
40-
assert_eq!(actual, expected, "{pattern:?} disagrees with baseline: {res:?}")
40+
assert_eq!(actual, expected, "{pattern:?} disagrees with baseline: {actual:?}")
4141
}
4242
}
4343
}
@@ -57,25 +57,25 @@ fn special_time_is_ok_for_now() {
5757
#[test]
5858
fn short() {
5959
assert_eq!(
60-
git_date::parse("1979-02-26"),
61-
Some(Time {
60+
git_date::parse("1979-02-26").expect("parsed date"),
61+
Time {
6262
seconds_since_unix_epoch: 288835200,
6363
offset_in_seconds: 0,
6464
sign: Sign::Plus,
65-
}),
65+
},
6666
"could not parse with SHORT format"
6767
);
6868
}
6969

7070
#[test]
7171
fn rfc2822() {
7272
assert_eq!(
73-
git_date::parse("Thu, 18 Aug 2022 12:45:06 +0800"),
74-
Some(Time {
73+
git_date::parse("Thu, 18 Aug 2022 12:45:06 +0800").expect("parsed rfc2822 string"),
74+
Time {
7575
seconds_since_unix_epoch: 1660797906,
7676
offset_in_seconds: 28800,
7777
sign: Sign::Plus,
78-
}),
78+
},
7979
"could not parse with RFC2822 format"
8080
);
8181
}

git-repository/src/repository/identity.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,13 @@ impl Personas {
125125
committer_email = committer_email.or_else(|| env_var("GIT_COMMITTER_EMAIL"));
126126
committer_date = std::env::var("GIT_COMMITTER_DATE")
127127
.ok()
128-
.and_then(|date| git_date::parse(&date));
128+
.and_then(|date| git_date::parse(&date).ok());
129129

130130
author_name = author_name.or_else(|| env_var("GIT_AUTHOR_NAME"));
131131
author_email = author_email.or_else(|| env_var("GIT_AUTHOR_EMAIL"));
132132
author_date = std::env::var("GIT_AUTHOR_DATE")
133133
.ok()
134-
.and_then(|date| git_date::parse(&date));
134+
.and_then(|date| git_date::parse(&date).ok());
135135

136136
user_email = user_email.or_else(|| env_var("EMAIL")); // NOTE: we don't have permission for this specific one…
137137
}

git-revision/src/spec/parse/function.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ where
435435
let time = nav
436436
.to_str()
437437
.ok()
438-
.and_then(git_date::parse)
438+
.and_then(|v| git_date::parse(v).ok())
439439
.ok_or_else(|| Error::Time { input: nav.into() })?;
440440
delegate
441441
.reflog(delegate::ReflogLookup::Date(time))

0 commit comments

Comments
 (0)