| ... | ... | @@ -89,7 +89,7 @@ pub fn parseTree(alloc: std.mem.Allocator, treefile: string) !Tree { |
| 89 | 89 | |
| 90 | 90 | while (iter.next()) |line| { |
| 91 | 91 | var jter = std.mem.split(u8, line, " "); |
| 92 | | const mode = try std.fmt.parseInt(u32, jter.next().?, 10); |
| 92 | const mode = jter.next().?; |
| 93 | 93 | const otype = std.meta.stringToEnum(Tree.Object.Id.Tag, jter.next().?).?; |
| 94 | 94 | const id_and_name = jter.next().?; |
| 95 | 95 | std.debug.assert(jter.next() == null); |
| ... | ... | @@ -101,7 +101,12 @@ pub fn parseTree(alloc: std.mem.Allocator, treefile: string) !Tree { |
| 101 | 101 | inline for (std.meta.fields(Tree.Object.Id)) |item| { |
| 102 | 102 | if (std.mem.eql(u8, item.name, @tagName(otype))) { |
| 103 | 103 | try children.append(.{ |
| 104 | | .mode = mode, |
| 104 | .mode = .{ |
| 105 | .type = @intToEnum(Tree.Object.Type, try std.fmt.parseInt(u16, mode[0..3], 10)), |
| 106 | .perm_user = @bitCast(Tree.Object.Perm, try std.fmt.parseInt(u3, mode[3..][0..1], 8)), |
| 107 | .perm_group = @bitCast(Tree.Object.Perm, try std.fmt.parseInt(u3, mode[4..][0..1], 8)), |
| 108 | .perm_other = @bitCast(Tree.Object.Perm, try std.fmt.parseInt(u3, mode[5..][0..1], 8)), |
| 109 | }, |
| 105 | 110 | .id = @unionInit(Tree.Object.Id, item.name, item.type{ .id = id }), |
| 106 | 111 | .name = name, |
| 107 | 112 | }); |
| ... | ... | @@ -132,7 +137,7 @@ pub const Tree = struct { |
| 132 | 137 | } |
| 133 | 138 | |
| 134 | 139 | pub const Object = struct { |
| 135 | | mode: u32, // git allegedly only uses a specific set of these. should it be an enum? |
| 140 | mode: Mode, |
| 136 | 141 | id: @This().Id, |
| 137 | 142 | name: string, |
| 138 | 143 | |
| ... | ... | @@ -143,5 +148,56 @@ pub const Tree = struct { |
| 143 | 148 | |
| 144 | 149 | pub const Tag = std.meta.Tag(@This()); |
| 145 | 150 | }; |
| 151 | |
| 152 | pub const Mode = struct { |
| 153 | type: Type, |
| 154 | perm_user: Perm, |
| 155 | perm_group: Perm, |
| 156 | perm_other: Perm, |
| 157 | |
| 158 | pub fn format(self: Mode, comptime fmt: string, options: std.fmt.FormatOptions, writer: anytype) !void { |
| 159 | _ = fmt; |
| 160 | _ = options; |
| 161 | |
| 162 | try writer.print("{}", .{self.type}); |
| 163 | try writer.print("{}", .{self.perm_user}); |
| 164 | try writer.print("{}", .{self.perm_group}); |
| 165 | try writer.print("{}", .{self.perm_other}); |
| 166 | } |
| 167 | }; |
| 168 | |
| 169 | pub const Type = enum(u16) { |
| 170 | file = 100, |
| 171 | directory = 40, |
| 172 | submodule = 160, |
| 173 | _, |
| 174 | |
| 175 | pub fn format(self: Type, comptime fmt: string, options: std.fmt.FormatOptions, writer: anytype) !void { |
| 176 | _ = fmt; |
| 177 | _ = options; |
| 178 | |
| 179 | try writer.writeByte(switch (self) { |
| 180 | .file => '-', |
| 181 | .directory => 'd', |
| 182 | .submodule => 'm', |
| 183 | _ => '?', |
| 184 | }); |
| 185 | } |
| 186 | }; |
| 187 | |
| 188 | pub const Perm = packed struct(u3) { |
| 189 | execute: bool, |
| 190 | write: bool, |
| 191 | read: bool, |
| 192 | |
| 193 | pub fn format(self: Perm, comptime fmt: string, options: std.fmt.FormatOptions, writer: anytype) !void { |
| 194 | _ = fmt; |
| 195 | _ = options; |
| 196 | |
| 197 | try writer.writeByte(if (self.read) 'r' else '-'); |
| 198 | try writer.writeByte(if (self.write) 'w' else '-'); |
| 199 | try writer.writeByte(if (self.execute) 'x' else '-'); |
| 200 | } |
| 201 | }; |
| 146 | 202 | }; |
| 147 | 203 | }; |