git-ext: Display/parse timezone offset in the format git2 expects.

The previous implementation of Display for Time is shown as absolute
minutes, whereas git expects HH:MM format.

The FromStr implementation for Author also did not correctly convert
+/-HHMM to absolute minutes.

Signed-off-by: xphoniex <xphoniex@users.noreply.github.com>
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
This commit is contained in:
xphoniex
2023-05-09 22:27:25 +01:00
committed by Fintan Halpenny
parent 0897f918e6
commit 98a6e69379
2 changed files with 36 additions and 3 deletions
+14 -2
View File
@@ -60,7 +60,9 @@ impl From<git2::Time> for Time {
impl fmt::Display for Time {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let sign = if self.offset.is_negative() { '-' } else { '+' };
write!(f, "{} {}{:0>4}", self.seconds, sign, self.offset.abs())
let hours = self.offset.abs() / 60;
let minutes = self.offset.abs() % 60;
write!(f, "{} {}{:0>2}{:0>2}", self.seconds, sign, hours, minutes)
}
}
@@ -110,7 +112,17 @@ impl FromStr for Author {
let mut components = s.split(' ');
let offset = match components.next_back() {
None => return Err(ParseError::Missing("offset")),
Some(offset) => offset.parse::<i32>().map_err(ParseError::Offset)?,
Some(offset) => {
// The offset is in the form of timezone offset,
// e.g. +0200, -0100. This needs to be converted into
// minutes. The first two digits in the offset are the
// number of hours in the offset, while the latter two
// digits are the number of minutes in the offset.
let tz_offset = offset.parse::<i32>().map_err(ParseError::Offset)?;
let hours = tz_offset / 100;
let minutes = tz_offset % 100;
hours * 60 + minutes
},
};
let time = match components.next_back() {
None => return Err(ParseError::Missing("time")),
+22 -1
View File
@@ -1,4 +1,4 @@
use std::{io, str::FromStr as _};
use std::{io, str::FromStr as _, string::ToString as _};
use radicle_git_ext::{
author::{self, Author},
@@ -242,3 +242,24 @@ fn write_valid_commit() {
.write(&repo);
assert!(valid.is_ok())
}
#[test]
fn author_roundtrip() {
let author = "author Fintan Halpenny <fintan.halpenny@gmail.com> 1669292989 +0000";
assert_eq!(
author.parse::<Author>().unwrap().to_string(),
author.to_string()
);
let author = "author Alexis Sellier <alexis@radicle.xyz> 1664467633 +0200";
assert_eq!(
author.parse::<Author>().unwrap().to_string(),
author.to_string()
);
let author = "author Alexis Sellier <alexis@radicle.xyz> 1664467633 -0200";
assert_eq!(
author.parse::<Author>().unwrap().to_string(),
author.to_string()
);
}