| ... | ... | @@ -64,3 +64,66 @@ pub const Commit = struct { |
| 64 | 64 | gpgsig: string, |
| 65 | 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 | }; |