Skip to content

Commit 1eb1e36

Browse files
committed
time serialization
1 parent f560bc5 commit 1eb1e36

File tree

5 files changed

+74
-12
lines changed

5 files changed

+74
-12
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-object/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ nom = { version = "6.0.0-alpha1", default-features = false, features = ["alloc"]
2626
smallvec = "1.4.0"
2727
serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"]}
2828
git-ref = { version = "0.1.0", path = "../git-ref" }
29+
itoa = "0.4.6"
2930

3031
[dev-dependencies]
3132
pretty_assertions = "0.6.1"

git-object/src/owned/object.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub mod signature {
2929
out.write_all(SPACE)?;
3030
out.write_all(&b"<"[..])?;
3131
out.write_all(validated_token(self.email.as_bstr())?)?;
32-
out.write_all(&b">"[..])?;
32+
out.write_all(&b"> "[..])?;
3333
self.time.write_to(out)?;
3434
Ok(())
3535
}

git-object/src/types.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use crate::ByteSlice;
1+
use crate::owned::SPACE;
2+
use bstr::ByteSlice;
23
use quick_error::quick_error;
3-
use std::ops::Deref;
4-
use std::{fmt, io};
4+
use std::{fmt, io, ops::Deref};
55

66
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
77
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
@@ -22,8 +22,30 @@ pub struct Time {
2222
}
2323

2424
impl Time {
25-
pub fn write_to(&self, out: impl io::Write) -> io::Result<()> {
26-
unimplemented!("time write to")
25+
pub fn write_to(&self, mut out: impl io::Write) -> io::Result<()> {
26+
itoa::write(&mut out, self.time)?;
27+
out.write_all(SPACE)?;
28+
out.write_all(&[match self.sign {
29+
Sign::Plus => b'+',
30+
Sign::Minus => b'-',
31+
}])?;
32+
33+
const ZERO: &[u8; 1] = b"0";
34+
35+
const SECONDS_PER_HOUR: i32 = 60 * 60;
36+
let hours = self.offset / SECONDS_PER_HOUR;
37+
assert!(hours < 25, "offset is more than a day: {}", hours);
38+
let minutes = (self.offset - (hours * SECONDS_PER_HOUR)) / 60;
39+
40+
if hours < 10 {
41+
out.write_all(ZERO)?;
42+
}
43+
itoa::write(&mut out, hours)?;
44+
45+
if minutes < 10 {
46+
out.write_all(ZERO)?;
47+
}
48+
itoa::write(&mut out, minutes).map(|_| ())
2749
}
2850
}
2951

git-object/tests/owned/mod.rs

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,50 @@
11
mod object {
2+
mod time {
3+
use bstr::ByteSlice;
4+
use git_object::{Sign, Time};
5+
6+
#[test]
7+
fn write_to() {
8+
for (time, expected) in &[
9+
(
10+
Time {
11+
time: 500,
12+
offset: 9000,
13+
sign: Sign::Plus,
14+
},
15+
"500 +0230",
16+
),
17+
(
18+
Time {
19+
time: 189009009,
20+
offset: 36000,
21+
sign: Sign::Minus,
22+
},
23+
"189009009 -1000",
24+
),
25+
(
26+
Time {
27+
time: 0,
28+
offset: 0,
29+
sign: Sign::Minus,
30+
},
31+
"0 -0000",
32+
),
33+
] {
34+
let mut output = Vec::new();
35+
time.write_to(&mut output).unwrap();
36+
assert_eq!(output.as_bstr(), expected);
37+
}
38+
}
39+
}
40+
241
mod signature {
3-
mod to_write {
4-
use bstr::ByteSlice;
5-
use git_object::{borrowed, owned};
42+
use bstr::ByteSlice;
43+
use git_object::{borrowed, owned};
644

7-
#[test]
8-
fn round_trip() {
9-
let input = b"Sebastian Thiel <byronimo@gmail.com> 1528473343 +0230";
45+
#[test]
46+
fn round_trip() {
47+
for input in &[&b"Sebastian Thiel <byronimo@gmail.com> 1528473343 +0230"[..]] {
1048
let signature: owned::Signature = borrowed::Signature::from_bytes(input).unwrap().into();
1149
let mut output = Vec::new();
1250
signature.write_to(&mut output).unwrap();

0 commit comments

Comments
 (0)