| ... | @@ -178,10 +178,26 @@ fn parseCommitUserAndAt(input: string) !Commit.UserAndAt { | ... | @@ -178,10 +178,26 @@ fn parseCommitUserAndAt(input: string) !Commit.UserAndAt { |
| 178 | _ = tz_part; | 178 | _ = tz_part; |
| 179 | std.debug.assert(email_part[0] == '<'); | 179 | std.debug.assert(email_part[0] == '<'); |
| 180 | std.debug.assert(email_part[email_part.len - 1] == '>'); | 180 | std.debug.assert(email_part[email_part.len - 1] == '>'); |
| | 181 | const name = name_part; |
| | 182 | const email = std.mem.trim(u8, email_part, "<>"); |
| | 183 | const at = time.DateTime.initUnix(try std.fmt.parseInt(u64, time_part, 10)); |
| | 184 | const email_md5 = blk: { |
| | 185 | const Algo = std.crypto.hash.Md5; |
| | 186 | var h = Algo.init(.{}); |
| | 187 | var out: [Algo.digest_length]u8 = undefined; |
| | 188 | h.update(email); |
| | 189 | h.final(&out); |
| | 190 | var res: [Algo.digest_length * 2]u8 = undefined; |
| | 191 | var fbs = std.io.fixedBufferStream(&res); |
| | 192 | try std.fmt.format(fbs.writer(), "{x}", .{std.fmt.fmtSliceHexLower(&out)}); |
| | 193 | break :blk res; |
| | 194 | }; |
| | 195 | |
| 181 | return .{ | 196 | return .{ |
| 182 | .name = name_part, | 197 | .name = name, |
| 183 | .email = std.mem.trim(u8, email_part, "<>"), | 198 | .email = email, |
| 184 | .at = time.DateTime.initUnix(try std.fmt.parseInt(u64, time_part, 10)), | 199 | .email_md5 = email_md5, |
| | 200 | .at = at, |
| 185 | }; | 201 | }; |
| 186 | } | 202 | } |
| 187 | | 203 | |
| ... | @@ -196,6 +212,7 @@ pub const Commit = struct { | ... | @@ -196,6 +212,7 @@ pub const Commit = struct { |
| 196 | pub const UserAndAt = struct { | 212 | pub const UserAndAt = struct { |
| 197 | name: string, | 213 | name: string, |
| 198 | email: string, | 214 | email: string, |
| | 215 | email_md5: [std.crypto.hash.Md5.digest_length * 2]u8, |
| 199 | at: time.DateTime, | 216 | at: time.DateTime, |
| 200 | }; | 217 | }; |
| 201 | }; | 218 | }; |