authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2023-04-25 23:23:08 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2023-04-25 23:23:08 -07:00
log7906b39ca320577f1579bf63b5095a33fbaedc4f
treea23496ed3c5e953d4b158096de0d36b0751b5057
parentef17e36eaa82709593a80634cd345ebfa6fac1c8

add parseTree() and Tree decls


1 files changed, 63 insertions(+), 0 deletions(-)

git.zig+63
...@@ -64,3 +64,66 @@ pub const Commit = struct {...@@ -64,3 +64,66 @@ pub const Commit = struct {
64 gpgsig: string,64 gpgsig: string,
65 message: string,65 message: string,
66};66};
67
68pub fn parseTree(alloc: std.mem.Allocator, treefile: string) !Tree {
69 var iter = std.mem.split(u8, treefile, "\n");
70 var children = std.ArrayList(Tree.Object).init(alloc);
71 errdefer children.deinit();
72
73 while (iter.next()) |line| {
74 var jter = std.mem.split(u8, line, " ");
75 const mode = try std.fmt.parseInt(u32, jter.next().?, 10);
76 const otype = std.meta.stringToEnum(Tree.Object.Id.Tag, jter.next().?).?;
77 const id_and_name = jter.next().?;
78 std.debug.assert(jter.next() == null);
79 const tab_pos = std.mem.indexOfScalar(u8, id_and_name, '\t').?; // why git. why.
80 std.debug.assert(tab_pos == 40);
81 const id = id_and_name[0..tab_pos][0..40];
82 const name = id_and_name[tab_pos + 1 ..];
83
84 inline for (std.meta.fields(Tree.Object.Id)) |item| {
85 if (std.mem.eql(u8, item.name, @tagName(otype))) {
86 try children.append(.{
87 .mode = mode,
88 .id = @unionInit(Tree.Object.Id, item.name, item.type{ .id = id }),
89 .name = name,
90 });
91 }
92 }
93 }
94 return Tree{
95 .children = try children.toOwnedSlice(),
96 };
97}
98
99pub const Tree = struct {
100 children: []const Object,
101
102 pub fn get(self: Tree, name: string) ?Object {
103 for (self.children) |item| {
104 if (std.mem.eql(u8, item.name, name)) {
105 return item;
106 }
107 }
108 return null;
109 }
110
111 pub fn getBlob(self: Tree, name: string) ?Object {
112 const o = self.get(name) orelse return null;
113 if (o.id != .blob) return null;
114 return o;
115 }
116
117 pub const Object = struct {
118 mode: u32, // git allegedly only uses a specific set of these. should it be an enum?
119 id: @This().Id,
120 name: string,
121
122 pub const Id = union(enum) {
123 blob: BlobId,
124 tree: TreeId,
125
126 pub const Tag = std.meta.Tag(@This());
127 };
128 };
129};