| ... | ... | @@ -163,26 +163,47 @@ pub fn formatType( |
| 163 | 163 | } |
| 164 | 164 | break :cf false; |
| 165 | 165 | }; |
| 166 | | |
| 167 | 166 | if (has_cust_fmt) return value.format(fmt, context, Errors, output); |
| 167 | |
| 168 | 168 | try output(context, @typeName(T)); |
| 169 | | if (comptime @typeId(T) == builtin.TypeId.Enum) { |
| 170 | | try output(context, "."); |
| 171 | | try formatType(@tagName(value), "", context, Errors, output); |
| 172 | | return; |
| 173 | | } |
| 174 | | comptime var field_i = 0; |
| 175 | | inline while (field_i < @memberCount(T)) : (field_i += 1) { |
| 176 | | if (field_i == 0) { |
| 177 | | try output(context, "{ ."); |
| 178 | | } else { |
| 179 | | try output(context, ", ."); |
| 180 | | } |
| 181 | | try output(context, @memberName(T, field_i)); |
| 182 | | try output(context, " = "); |
| 183 | | try formatType(@field(value, @memberName(T, field_i)), "", context, Errors, output); |
| 169 | switch (comptime @typeId(T)) { |
| 170 | builtin.TypeId.Enum => { |
| 171 | try output(context, "."); |
| 172 | try formatType(@tagName(value), "", context, Errors, output); |
| 173 | return; |
| 174 | }, |
| 175 | builtin.TypeId.Struct => { |
| 176 | comptime var field_i = 0; |
| 177 | inline while (field_i < @memberCount(T)) : (field_i += 1) { |
| 178 | if (field_i == 0) { |
| 179 | try output(context, "{ ."); |
| 180 | } else { |
| 181 | try output(context, ", ."); |
| 182 | } |
| 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 | 207 | return; |
| 187 | 208 | }, |
| 188 | 209 | builtin.TypeId.Pointer => |ptr_info| switch (ptr_info.size) { |
| ... | ... | @@ -1194,6 +1215,66 @@ test "fmt.format" { |
| 1194 | 1215 | try testFmt("point: (10.200,2.220)\n", "point: {}\n", value); |
| 1195 | 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 | 1280 | fn testFmt(expected: []const u8, comptime template: []const u8, args: ...) !void { |