| ... | @@ -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 | |
| | 68 | pub 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 | |
| | 99 | pub 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 | }; |