From a6e6daa88e6d294fbb7b6173b3cc37bcad28ccc8 Mon Sep 17 00:00:00 2001 From: patrick-scho Date: Mon, 12 Aug 2024 14:32:59 +0200 Subject: [PATCH] Implement Object parsing --- git.zig | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/git.zig b/git.zig index 8c44fb6..0d42c2a 100644 --- a/git.zig +++ b/git.zig @@ -33,6 +33,55 @@ const Object = struct { .data = data, }; } + pub fn parse(self: Object, alloc: Alloc) !union(enum) { c: Commit, t: Tree, b: Blob } { + switch (self.kind) { + 1 => { + const authorOffset = std.mem.indexOf(u8, self.data, "author ") orelse return error.InvalidCommitFormat; + const authorNewline = std.mem.indexOfScalarPos(u8, self.data, authorOffset, '\n') orelse return error.InvalidCommitFormat; + const committerOffset = std.mem.indexOf(u8, self.data, "committer ") orelse return error.InvalidCommitFormat; + const committerNewline = std.mem.indexOfScalarPos(u8, self.data, committerOffset, '\n') orelse return error.InvalidCommitFormat; + + return .{ + .c = Commit{ + .tree = try std.fmt.parseUnsigned(Id, self.data[5..45], 16), + .parent = try std.fmt.parseUnsigned(Id, self.data[53..93], 16), + .author = self.data[authorOffset..authorNewline], + .committer = self.data[committerOffset..committerNewline], + .message = self.data[committerNewline + 1 .. self.data.len], + }, + }; + }, + 2 => { + var t = Tree.init(alloc); + + var offset: usize = 0; + + while (offset < self.data.len - 1) { + const spaceOffset = std.mem.indexOfScalarPos(u8, self.data, offset, ' ') orelse return error.InvalidTreeFormat; + const zeroOffset = std.mem.indexOfScalarPos(u8, self.data, spaceOffset, 0) orelse return error.InvalidTreeFormat; + + try t.append(.{ + .permissions = self.data[offset..spaceOffset], + .name = self.data[spaceOffset + 1 .. zeroOffset], + .id = std.mem.readVarInt(Id, self.data[zeroOffset + 1 .. zeroOffset + 21], .big), + }); + + offset = zeroOffset + 21; + } + + return .{ .t = t }; + }, + 3 => { + return .{ + .b = Blob{ .data = self.data }, + }; + }, + 4 => { + return error.TagNotImplemented; + }, + else => return error.UnknownGitObjectType, + } + } // pub fn getCommit(self: *Object) Commit {} // pub fn getBlob(self: *Object) Blob {} }; -- 2.50.1