| ... | @@ -163,26 +163,47 @@ pub fn formatType( | ... | @@ -163,26 +163,47 @@ pub fn formatType( |
| 163 | } | 163 | } |
| 164 | break :cf false; | 164 | break :cf false; |
| 165 | }; | 165 | }; |
| 166 | | | |
| 167 | if (has_cust_fmt) return value.format(fmt, context, Errors, output); | 166 | if (has_cust_fmt) return value.format(fmt, context, Errors, output); |
| | 167 | |
| 168 | try output(context, @typeName(T)); | 168 | try output(context, @typeName(T)); |
| 169 | if (comptime @typeId(T) == builtin.TypeId.Enum) { | 169 | switch (comptime @typeId(T)) { |
| 170 | try output(context, "."); | 170 | builtin.TypeId.Enum => { |
| 171 | try formatType(@tagName(value), "", context, Errors, output); | 171 | try output(context, "."); |
| 172 | return; | 172 | try formatType(@tagName(value), "", context, Errors, output); |
| 173 | } | 173 | return; |
| 174 | comptime var field_i = 0; | 174 | }, |
| 175 | inline while (field_i < @memberCount(T)) : (field_i += 1) { | 175 | builtin.TypeId.Struct => { |
| 176 | if (field_i == 0) { | 176 | comptime var field_i = 0; |
| 177 | try output(context, "{ ."); | 177 | inline while (field_i < @memberCount(T)) : (field_i += 1) { |
| 178 | } else { | 178 | if (field_i == 0) { |
| 179 | try output(context, ", ."); | 179 | try output(context, "{ ."); |
| 180 | } | 180 | } else { |
| 181 | try output(context, @memberName(T, field_i)); | 181 | try output(context, ", ."); |
| 182 | try output(context, " = "); | 182 | } |
| 183 | try formatType(@field(value, @memberName(T, field_i)), "", context, Errors, output); | 183 | try output(context, @memberName(T, field_i)); |
| | 184 | try output(context, " = "); |
| | 185 | try formatType(@field(value, @memberName(T, field_i)), "", context, Errors, output); |
| | 186 | } |
| | 187 | try output(context, " }"); |
| | 188 | }, |
| | 189 | builtin.TypeId.Union => { |
| | 190 | const info = @typeInfo(T).Union; |
| | 191 | if(info.tag_type) |UnionTagType| { |
| | 192 | try output(context, "{ ."); |
| | 193 | try output(context, @tagName(UnionTagType(value))); |
| | 194 | try output(context, " = "); |
| | 195 | inline for(info.fields) |u_field| { |
| | 196 | if(@enumToInt(UnionTagType(value)) == u_field.enum_field.?.value) { |
| | 197 | try formatType(@field(value, u_field.name), "", context, Errors, output); |
| | 198 | } |
| | 199 | } |
| | 200 | try output(context, " }"); |
| | 201 | } else { |
| | 202 | try format(context, Errors, output, "@{x}", @ptrToInt(&value)); |
| | 203 | } |
| | 204 | }, |
| | 205 | else => unreachable, |
| 184 | } | 206 | } |
| 185 | try output(context, " }"); | | |
| 186 | return; | 207 | return; |
| 187 | }, | 208 | }, |
| 188 | builtin.TypeId.Pointer => |ptr_info| switch (ptr_info.size) { | 209 | builtin.TypeId.Pointer => |ptr_info| switch (ptr_info.size) { |
| ... | @@ -1194,6 +1215,66 @@ test "fmt.format" { | ... | @@ -1194,6 +1215,66 @@ test "fmt.format" { |
| 1194 | try testFmt("point: (10.200,2.220)\n", "point: {}\n", value); | 1215 | try testFmt("point: (10.200,2.220)\n", "point: {}\n", value); |
| 1195 | try testFmt("dim: 10.200x2.220\n", "dim: {d}\n", value); | 1216 | try testFmt("dim: 10.200x2.220\n", "dim: {d}\n", value); |
| 1196 | } | 1217 | } |
| | 1218 | //struct format |
| | 1219 | { |
| | 1220 | const S = struct { |
| | 1221 | a: u32, |
| | 1222 | b: error, |
| | 1223 | }; |
| | 1224 | |
| | 1225 | const inst = S { |
| | 1226 | .a = 456, |
| | 1227 | .b = error.Unused, |
| | 1228 | }; |
| | 1229 | |
| | 1230 | try testFmt("S{ .a = 456, .b = error.Unused }", "{}", inst); |
| | 1231 | } |
| | 1232 | //union format |
| | 1233 | { |
| | 1234 | const TU = union(enum) |
| | 1235 | { |
| | 1236 | float: f32, |
| | 1237 | int: u32, |
| | 1238 | }; |
| | 1239 | |
| | 1240 | const UU = union |
| | 1241 | { |
| | 1242 | float: f32, |
| | 1243 | int: u32, |
| | 1244 | }; |
| | 1245 | |
| | 1246 | const EU = extern union |
| | 1247 | { |
| | 1248 | float: f32, |
| | 1249 | int: u32, |
| | 1250 | }; |
| | 1251 | |
| | 1252 | const tu_inst = TU{ .int = 123, }; |
| | 1253 | const uu_inst = UU{ .int = 456, }; |
| | 1254 | const eu_inst = EU{ .float = 321.123, }; |
| | 1255 | |
| | 1256 | try testFmt("TU{ .int = 123 }", "{}", tu_inst); |
| | 1257 | |
| | 1258 | var buf: [100]u8 = undefined; |
| | 1259 | const uu_result = try bufPrint(buf[0..], "{}", uu_inst); |
| | 1260 | debug.assert(mem.eql(u8, uu_result[0..3], "UU@")); |
| | 1261 | |
| | 1262 | const eu_result = try bufPrint(buf[0..], "{}", eu_inst); |
| | 1263 | debug.assert(mem.eql(u8, uu_result[0..3], "EU@")); |
| | 1264 | } |
| | 1265 | //enum format |
| | 1266 | { |
| | 1267 | const E = enum |
| | 1268 | { |
| | 1269 | One, |
| | 1270 | Two, |
| | 1271 | Three, |
| | 1272 | }; |
| | 1273 | |
| | 1274 | const inst = E.Two; |
| | 1275 | |
| | 1276 | try testFmt("E.Two", "{}", inst); |
| | 1277 | } |
| 1197 | } | 1278 | } |
| 1198 | | 1279 | |
| 1199 | fn testFmt(expected: []const u8, comptime template: []const u8, args: ...) !void { | 1280 | fn testFmt(expected: []const u8, comptime template: []const u8, args: ...) !void { |