authorgravatar for mason@gamesbymason.comMason Remaley <mason@gamesbymason.com> 2026-07-18 21:39:17-07:00
committergravatar for mason@gamesbymason.comMason Remaley <mason@gamesbymason.com> 2026-09-26 12:35:38-07:00
log07149649ce9201399233628d2dea61ebb061c430
tree7e9877f816cb20eb766b3f3edd8c85a593f00caa
parent9e87e807ab65449845d12eaa3d98e2792194354d

Accept options structs instead of args

I wrote this API, and even I can't remember what order the arguments are in. Furthermore, the types won't be enough to distinguish between them when I add an arena alongside the GPA in a followup.

1 files changed, 1298 insertions(+), 615 deletions(-)

lib/std/zon/parse.zig+1298-615
...@@ -24,47 +24,6 @@ const ArrayList = std.ArrayList;...@@ -24,47 +24,6 @@ const ArrayList = std.ArrayList;
24/// Rename when adding or removing support for a type.24/// Rename when adding or removing support for a type.
25const valid_types = {};25const valid_types = {};
2626
27/// Deprecated.
28pub const Options = FromOptions;
29
30/// Configuration for the `from*` functions.
31pub const FromOptions = struct {
32 /// If true, unknown fields do not error.
33 ignore_unknown_fields: bool = false,
34 /// If true, the parser cleans up partially parsed values on error. This requires some extra
35 /// bookkeeping, so you may want to turn it off if you don't need this feature (e.g. because
36 /// you're using arena allocation.)
37 free_on_error: bool = true,
38
39 fn toParserOptions(self: FromOptions) Parser.Options {
40 return .{
41 .ignore_unknown_fields = self.ignore_unknown_fields,
42 .ignore_missing_fields = false,
43 .free_on_error = self.free_on_error,
44 .free_on_write = false,
45 };
46 }
47};
48
49/// Configuration for the `updateFrom*` variants.
50pub const UpdateFromOptions = struct {
51 /// If true, unknown fields do not error.
52 ignore_unknown_fields: bool = false,
53 /// If true, the old values of overriden fields are freed. You may want to turn this off if you
54 /// are updating a value that shouldn't be freed e.g. because it contains Zig string literals.
55 /// In this case, you can use arena allocation.
56 free_on_write: bool = true,
57
58 fn toParserOptions(self: UpdateFromOptions) Parser.Options {
59 return .{
60 .ignore_unknown_fields = self.ignore_unknown_fields,
61 .ignore_missing_fields = true,
62 .free_on_error = false,
63 .free_on_write = true,
64 };
65 }
66};
67
68pub const Error = union(enum) {27pub const Error = union(enum) {
69 zoir: Zoir.CompileError,28 zoir: Zoir.CompileError,
70 type_check: Error.TypeCheckFailure,29 type_check: Error.TypeCheckFailure,
...@@ -279,6 +238,19 @@ pub const Diagnostics = struct {...@@ -279,6 +238,19 @@ pub const Diagnostics = struct {
279 }238 }
280};239};
281240
241pub const FromSliceOptions = struct {
242 gpa: Allocator,
243 source: [:0]const u8,
244 /// Write human readable error messages here.
245 diag: ?*Diagnostics,
246 /// If true, unknown fields do not error.
247 ignore_unknown_fields: bool = false,
248 /// If true, the parser cleans up partially parsed values on error. This requires some extra
249 /// bookkeeping, so you may want to turn it off if you don't need this feature (e.g. because
250 /// you're using arena allocation.)
251 free_on_error: bool = true,
252};
253
282/// Parses the given slice as ZON.254/// Parses the given slice as ZON.
283///255///
284/// Returns `error.OutOfMemory` on allocation failure, or `error.ParseZon` error if the ZON is256/// Returns `error.OutOfMemory` on allocation failure, or `error.ParseZon` error if the ZON is
...@@ -291,15 +263,27 @@ pub const Diagnostics = struct {...@@ -291,15 +263,27 @@ pub const Diagnostics = struct {
291/// doesn't need to be freed.263/// doesn't need to be freed.
292///264///
293/// An allocator is still required for temporary allocations made during parsing.265/// An allocator is still required for temporary allocations made during parsing.
294pub fn fromSlice(266pub fn fromSlice(T: type, options: FromSliceOptions) error{ OutOfMemory, ParseZon }!T {
295 T: type,
296 gpa: Allocator,
297 source: [:0]const u8,
298 diag: ?*Diagnostics,
299 options: FromOptions,
300) error{ OutOfMemory, ParseZon }!T {
301 comptime assert(!requiresAllocator(T));267 comptime assert(!requiresAllocator(T));
302 return fromSliceAlloc(T, gpa, source, diag, options);268 return fromSliceAlloc(T, options);
269}
270
271pub fn UpdateFromSliceOptions(T: type) type {
272 return struct {
273 gpa: Allocator,
274 /// The value to update.
275 value: *T,
276 /// The ZON source.
277 source: [:0]const u8,
278 /// Write human readable error messages here.
279 diag: ?*Diagnostics,
280 /// If true, unknown fields do not error.
281 ignore_unknown_fields: bool = false,
282 /// If true, the old values of overriden fields are freed. You may want to turn this off if you
283 /// are updating a value that shouldn't be freed e.g. because it contains Zig string literals.
284 /// In this case, you can use arena allocation.
285 free_on_write: bool = true,
286 };
303}287}
304288
305/// Similar to `fromSlice`, but updates an existing value `current`. Fields not specified by ZON are289/// Similar to `fromSlice`, but updates an existing value `current`. Fields not specified by ZON are
...@@ -307,45 +291,52 @@ pub fn fromSlice(...@@ -307,45 +291,52 @@ pub fn fromSlice(
307/// failure, values that were updated prior to the failure are left updated.291/// failure, values that were updated prior to the failure are left updated.
308pub fn updateFromSlice(292pub fn updateFromSlice(
309 T: type,293 T: type,
310 gpa: Allocator,294 options: UpdateFromSliceOptions(T),
311 current: *T,
312 source: [:0]const u8,
313 diag: ?*Diagnostics,
314 options: UpdateFromOptions,
315) error{ OutOfMemory, ParseZon }!void {295) error{ OutOfMemory, ParseZon }!void {
316 comptime assert(!requiresAllocator(T));296 comptime assert(!requiresAllocator(T));
317 try updateFromSliceAlloc(T, gpa, current, source, diag, options);297 try updateFromSliceAlloc(T, options);
318}298}
319299
300pub const FromSliceAllocOptions = FromSliceOptions;
301
320/// Like `fromSlice`, but the result may contain pointers. To automatically free the result, see302/// Like `fromSlice`, but the result may contain pointers. To automatically free the result, see
321/// `free`.303/// `free`.
322pub fn fromSliceAlloc(304pub fn fromSliceAlloc(T: type, options: FromSliceOptions) error{ OutOfMemory, ParseZon }!T {
323 T: type,
324 gpa: Allocator,
325 source: [:0]const u8,
326 diag: ?*Diagnostics,
327 options: FromOptions,
328) error{ OutOfMemory, ParseZon }!T {
329 var result: T = undefined;305 var result: T = undefined;
330 try parseSliceAlloc(T, &result, gpa, source, diag, options.toParserOptions());306 try parseSliceAlloc(T, &result, options.gpa, options.source, options.diag, .{
307 .ignore_unknown_fields = options.ignore_unknown_fields,
308 .ignore_missing_fields = false,
309 .free_on_error = options.free_on_error,
310 .free_on_write = false,
311 });
331 return result;312 return result;
332}313}
333314
315pub const UpdateFromSliceAllocOptions = UpdateFromSliceOptions;
316
334/// Like updateFromSlice`, but the result may contain pointers.317/// Like updateFromSlice`, but the result may contain pointers.
335pub fn updateFromSliceAlloc(318pub fn updateFromSliceAlloc(
336 T: type,319 T: type,
337 gpa: Allocator,320 options: UpdateFromSliceAllocOptions(T),
338 current: *T,
339 source: [:0]const u8,
340 diag: ?*Diagnostics,
341 options: UpdateFromOptions,
342) error{ OutOfMemory, ParseZon }!void {321) error{ OutOfMemory, ParseZon }!void {
343 try parseSliceAlloc(T, current, gpa, source, diag, options.toParserOptions());322 try parseSliceAlloc(
323 T,
324 options.value,
325 options.gpa,
326 options.source,
327 options.diag,
328 .{
329 .ignore_unknown_fields = options.ignore_unknown_fields,
330 .ignore_missing_fields = true,
331 .free_on_error = false,
332 .free_on_write = options.free_on_write,
333 },
334 );
344}335}
345336
346fn parseSliceAlloc(337fn parseSliceAlloc(
347 T: type,338 T: type,
348 current: *T,339 out: *T,
349 gpa: Allocator,340 gpa: Allocator,
350 source: [:0]const u8,341 source: [:0]const u8,
351 diag: ?*Diagnostics,342 diag: ?*Diagnostics,
...@@ -363,92 +354,167 @@ fn parseSliceAlloc(...@@ -363,92 +354,167 @@ fn parseSliceAlloc(
363 defer if (diag == null) zoir.deinit(gpa);354 defer if (diag == null) zoir.deinit(gpa);
364355
365 if (diag) |s| s.* = .{};356 if (diag) |s| s.* = .{};
366 try parseZoirAlloc(T, gpa, current, ast, zoir, .root, diag, options);357 try parseZoirAlloc(T, out, gpa, ast, zoir, .root, diag, options);
367}358}
368359
369/// Like `fromSlice`, but operates on `Zoir` instead of ZON source.360pub const FromZoirOptions = struct {
370pub fn fromZoir(361 /// The AST for this this ZON value.
371 T: type,
372 ast: Ast,362 ast: Ast,
363 /// The zig object intermediate representation of this ZON value.
373 zoir: Zoir,364 zoir: Zoir,
374 node: Zoir.Node.Index,365 /// The node to start parsing at.
366 node: Zoir.Node.Index = .root,
367 /// Write human readable error messages here.
375 diag: ?*Diagnostics,368 diag: ?*Diagnostics,
376 options: FromOptions,369 /// If true, unknown fields do not error.
377) error{ParseZon}!T {370 ignore_unknown_fields: bool = false,
371 /// If true, the parser cleans up partially parsed values on error. This requires some extra
372 /// bookkeeping, so you may want to turn it off if you don't need this feature (e.g. because
373 /// you're using arena allocation.)
374 free_on_error: bool = true,
375};
376
377/// Like `fromSlice`, but operates on `Zoir` instead of ZON source.
378pub fn fromZoir(T: type, options: FromZoirOptions) error{ParseZon}!T {
378 comptime assert(!requiresAllocator(T));379 comptime assert(!requiresAllocator(T));
379 return fromZoirAlloc(380 return fromZoirAlloc(T, .{
380 T,381 .gpa = .failing,
381 .failing,382 .ast = options.ast,
382 ast,383 .zoir = options.zoir,
383 zoir,384 .node = options.node,
384 node,385 .diag = options.diag,
385 diag,386 .ignore_unknown_fields = options.ignore_unknown_fields,
386 options,387 .free_on_error = options.free_on_error,
387 ) catch |err| switch (err) {388 }) catch |err| switch (err) {
388 error.OutOfMemory => unreachable, // Checked by comptime assertion above389 error.OutOfMemory => unreachable, // Checked by comptime assertion above
389 else => |e| return e,390 else => |e| return e,
390 };391 };
391}392}
392393
394pub fn UpdateFromZoirOptions(T: type) type {
395 return struct {
396 value: *T,
397 /// The AST for this ZON value.
398 ast: Ast,
399 /// The zig object intermediate representation of this ZON value.
400 zoir: Zoir,
401 /// The node to start parsing at.
402 node: Zoir.Node.Index = .root,
403 /// Write human readable error messages here.
404 diag: ?*Diagnostics,
405 /// If true, unknown fields do not error.
406 ignore_unknown_fields: bool = false,
407 /// If true, the old values of overriden fields are freed. You may want to turn this off if you
408 /// are updating a value that shouldn't be freed e.g. because it contains Zig string literals.
409 /// In this case, you can use arena allocation.
410 free_on_write: bool = true,
411 };
412}
413
393/// Like `updateSlice`, but operates on `Zoir` instead of ZON source.414/// Like `updateSlice`, but operates on `Zoir` instead of ZON source.
394pub fn updateFromZoir(415pub fn updateFromZoir(
395 T: type,416 T: type,
396 current: *T,417 options: UpdateFromZoirOptions(T),
397 ast: Ast,
398 zoir: Zoir,
399 node: Zoir.Node.Index,
400 diag: ?*Diagnostics,
401 options: UpdateFromOptions,
402) error{ParseZon}!void {418) error{ParseZon}!void {
403 comptime assert(!requiresAllocator(T));419 comptime assert(!requiresAllocator(T));
404 updateFromZoirAlloc(420 updateFromZoirAlloc(T, .{
405 T,421 .gpa = .failing,
406 .failing,422 .value = options.value,
407 current,423 .ast = options.ast,
408 ast,424 .zoir = options.zoir,
409 zoir,425 .node = options.node,
410 node,426 .diag = options.diag,
411 diag,427 .ignore_unknown_fields = options.ignore_unknown_fields,
412 options,428 .free_on_write = options.free_on_write,
413 ) catch |err| switch (err) {429 }) catch |err| switch (err) {
414 error.OutOfMemory => unreachable, // Checked by comptime assertion above430 error.OutOfMemory => unreachable, // Checked by comptime assertion above
415 else => |e| return e,431 else => |e| return e,
416 };432 };
417}433}
418434
419/// Like `fromSliceAlloc`, but operates on `Zoir` instead of ZON source.435pub const FromZoirAllocOptions = struct {
420pub fn fromZoirAlloc(
421 T: type,
422 gpa: Allocator,436 gpa: Allocator,
437 /// The AST for this ZON value.
423 ast: Ast,438 ast: Ast,
439 /// The zig object intermediate representation of this ZON value.
424 zoir: Zoir,440 zoir: Zoir,
425 node: Zoir.Node.Index,441 /// The node to start parsing at.
442 node: Zoir.Node.Index = .root,
443 /// Write human readable error messages here.
426 diag: ?*Diagnostics,444 diag: ?*Diagnostics,
427 options: FromOptions,445 /// If true, unknown fields do not error.
428) error{ OutOfMemory, ParseZon }!T {446 ignore_unknown_fields: bool = false,
447 /// If true, the parser cleans up partially parsed values on error. This requires some extra
448 /// bookkeeping, so you may want to turn it off if you don't need this feature (e.g. because
449 /// you're using arena allocation.)
450 free_on_error: bool = true,
451};
452
453/// Like `fromSliceAlloc`, but operates on `Zoir` instead of ZON source.
454pub fn fromZoirAlloc(T: type, options: FromZoirAllocOptions) error{ OutOfMemory, ParseZon }!T {
429 var out: T = undefined;455 var out: T = undefined;
430 try parseZoirAlloc(T, gpa, &out, ast, zoir, node, diag, options.toParserOptions());456 try parseZoirAlloc(
457 T,
458 &out,
459 options.gpa,
460 options.ast,
461 options.zoir,
462 options.node,
463 options.diag,
464 .{
465 .ignore_unknown_fields = options.ignore_unknown_fields,
466 .ignore_missing_fields = false,
467 .free_on_error = options.free_on_error,
468 .free_on_write = false,
469 },
470 );
431 return out;471 return out;
432}472}
433473
474pub fn UpdateFromZoirAllocOptions(T: type) type {
475 return struct {
476 gpa: Allocator,
477 value: *T,
478 ast: Ast,
479 zoir: Zoir,
480 node: Zoir.Node.Index = .root,
481 /// Write human readable error messages here.
482 diag: ?*Diagnostics,
483 /// If true, unknown fields do not error.
484 ignore_unknown_fields: bool = false,
485 /// If true, the old values of overriden fields are freed. You may want to turn this off if you
486 /// are updating a value that shouldn't be freed e.g. because it contains Zig string literals.
487 /// In this case, you can use arena allocation.
488 free_on_write: bool = true,
489 };
490}
491
434/// Like updateSliceAlloc`, but operates on `Zoir` instead of ZON source.492/// Like updateSliceAlloc`, but operates on `Zoir` instead of ZON source.
435pub fn updateFromZoirAlloc(493pub fn updateFromZoirAlloc(
436 T: type,494 T: type,
437 gpa: Allocator,495 options: UpdateFromZoirAllocOptions(T),
438 current: *T,
439 ast: Ast,
440 zoir: Zoir,
441 node: Zoir.Node.Index,
442 diag: ?*Diagnostics,
443 options: UpdateFromOptions,
444) error{ OutOfMemory, ParseZon }!void {496) error{ OutOfMemory, ParseZon }!void {
445 return parseZoirAlloc(T, gpa, current, ast, zoir, node, diag, options.toParserOptions());497 return parseZoirAlloc(
498 T,
499 options.value,
500 options.gpa,
501 options.ast,
502 options.zoir,
503 options.node,
504 options.diag,
505 .{
506 .ignore_unknown_fields = options.ignore_unknown_fields,
507 .ignore_missing_fields = true,
508 .free_on_error = false,
509 .free_on_write = options.free_on_write,
510 },
511 );
446}512}
447513
448fn parseZoirAlloc(514fn parseZoirAlloc(
449 T: type,515 T: type,
450 gpa: Allocator,
451 out: *T,516 out: *T,
517 gpa: Allocator,
452 ast: Ast,518 ast: Ast,
453 zoir: Zoir,519 zoir: Zoir,
454 node: Zoir.Node.Index,520 node: Zoir.Node.Index,
...@@ -1449,7 +1515,7 @@ test "std.zon ast errors" {...@@ -1449,7 +1515,7 @@ test "std.zon ast errors" {
1449 defer diag.deinit(gpa);1515 defer diag.deinit(gpa);
1450 try std.testing.expectError(1516 try std.testing.expectError(
1451 error.ParseZon,1517 error.ParseZon,
1452 fromSlice(struct {}, gpa, ".{.x = 1 .y = 2}", &diag, .{}),1518 fromSlice(struct {}, .{ .gpa = gpa, .source = ".{.x = 1 .y = 2}", .diag = &diag }),
1453 );1519 );
1454 try std.testing.expectFmt("1:13: error: expected ',' after initializer\n", "{f}", .{diag});1520 try std.testing.expectFmt("1:13: error: expected ',' after initializer\n", "{f}", .{diag});
1455}1521}
...@@ -1457,20 +1523,28 @@ test "std.zon ast errors" {...@@ -1457,20 +1523,28 @@ test "std.zon ast errors" {
1457test "std.zon comments" {1523test "std.zon comments" {
1458 const gpa = std.testing.allocator;1524 const gpa = std.testing.allocator;
14591525
1460 try std.testing.expectEqual(@as(u8, 10), fromSlice(u8, gpa,1526 try std.testing.expectEqual(@as(u8, 10), fromSlice(u8, .{
1527 .gpa = gpa,
1528 .source =
1461 \\// comment1529 \\// comment
1462 \\10 // comment1530 \\10 // comment
1463 \\// comment1531 \\// comment
1464 , null, .{}));1532 ,
1533 .diag = null,
1534 }));
14651535
1466 {1536 {
1467 var diag: Diagnostics = .{};1537 var diag: Diagnostics = .{};
1468 defer diag.deinit(gpa);1538 defer diag.deinit(gpa);
1469 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa,1539 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
1540 .gpa = gpa,
1541 .source =
1470 \\//! comment1542 \\//! comment
1471 \\10 // comment1543 \\10 // comment
1472 \\// comment1544 \\// comment
1473 , &diag, .{}));1545 ,
1546 .diag = &diag,
1547 }));
1474 try std.testing.expectFmt(1548 try std.testing.expectFmt(
1475 "1:1: error: expected expression, found 'a document comment'\n",1549 "1:1: error: expected expression, found 'a document comment'\n",
1476 "{f}",1550 "{f}",
...@@ -1481,26 +1555,24 @@ test "std.zon comments" {...@@ -1481,26 +1555,24 @@ test "std.zon comments" {
14811555
1482test "std.zon failure/oom formatting" {1556test "std.zon failure/oom formatting" {
1483 const gpa = std.testing.allocator;1557 const gpa = std.testing.allocator;
1484 var failing_allocator = std.testing.FailingAllocator.init(gpa, .{
1485 .fail_index = 0,
1486 .resize_fail_index = 0,
1487 });
1488 var diag: Diagnostics = .{};1558 var diag: Diagnostics = .{};
1489 defer diag.deinit(gpa);1559 defer diag.deinit(gpa);
1490 try std.testing.expectError(error.OutOfMemory, fromSliceAlloc(1560 try std.testing.expectError(error.OutOfMemory, fromSliceAlloc([]const u8, .{
1491 []const u8,1561 .gpa = .failing,
1492 failing_allocator.allocator(),1562 .source = "\"foo\"",
1493 "\"foo\"",1563 .diag = &diag,
1494 &diag,1564 }));
1495 .{},
1496 ));
1497 try std.testing.expectFmt("", "{f}", .{diag});1565 try std.testing.expectFmt("", "{f}", .{diag});
1498}1566}
14991567
1500test "std.zon fromSliceAlloc syntax error" {1568test "std.zon fromSliceAlloc syntax error" {
1501 try std.testing.expectError(1569 try std.testing.expectError(
1502 error.ParseZon,1570 error.ParseZon,
1503 fromSlice(u8, std.testing.allocator, ".{", null, .{}),1571 fromSlice(u8, .{
1572 .gpa = std.testing.allocator,
1573 .source = ".{",
1574 .diag = null,
1575 }),
1504 );1576 );
1505}1577}
15061578
...@@ -1509,17 +1581,33 @@ test "std.zon optional" {...@@ -1509,17 +1581,33 @@ test "std.zon optional" {
15091581
1510 // Basic usage1582 // Basic usage
1511 {1583 {
1512 const none = try fromSlice(?u32, gpa, "null", null, .{});1584 const none = try fromSlice(?u32, .{
1585 .gpa = gpa,
1586 .source = "null",
1587 .diag = null,
1588 });
1513 try std.testing.expect(none == null);1589 try std.testing.expect(none == null);
1514 const some = try fromSlice(?u32, gpa, "1", null, .{});1590 const some = try fromSlice(?u32, .{
1591 .gpa = gpa,
1592 .source = "1",
1593 .diag = null,
1594 });
1515 try std.testing.expect(some.? == 1);1595 try std.testing.expect(some.? == 1);
1516 }1596 }
15171597
1518 // Deep free1598 // Deep free
1519 {1599 {
1520 const none = try fromSliceAlloc(?[]const u8, gpa, "null", null, .{});1600 const none = try fromSliceAlloc(?[]const u8, .{
1601 .gpa = gpa,
1602 .source = "null",
1603 .diag = null,
1604 });
1521 try std.testing.expect(none == null);1605 try std.testing.expect(none == null);
1522 const some = try fromSliceAlloc(?[]const u8, gpa, "\"foo\"", null, .{});1606 const some = try fromSliceAlloc(?[]const u8, .{
1607 .gpa = gpa,
1608 .source = "\"foo\"",
1609 .diag = null,
1610 });
1523 defer free(gpa, some);1611 defer free(gpa, some);
1524 try std.testing.expectEqualStrings("foo", some.?);1612 try std.testing.expectEqualStrings("foo", some.?);
1525 }1613 }
...@@ -1533,18 +1621,42 @@ test "std.zon unions" {...@@ -1533,18 +1621,42 @@ test "std.zon unions" {
1533 const Tagged = union(enum) { x: f32, @"y y": bool, z, @"z z" };1621 const Tagged = union(enum) { x: f32, @"y y": bool, z, @"z z" };
1534 const Untagged = union { x: f32, @"y y": bool, z: void, @"z z": void };1622 const Untagged = union { x: f32, @"y y": bool, z: void, @"z z": void };
15351623
1536 const tagged_x = try fromSlice(Tagged, gpa, ".{.x = 1.5}", null, .{});1624 const tagged_x = try fromSlice(Tagged, .{
1625 .gpa = gpa,
1626 .source = ".{.x = 1.5}",
1627 .diag = null,
1628 });
1537 try std.testing.expectEqual(Tagged{ .x = 1.5 }, tagged_x);1629 try std.testing.expectEqual(Tagged{ .x = 1.5 }, tagged_x);
1538 const tagged_y = try fromSlice(Tagged, gpa, ".{.@\"y y\" = true}", null, .{});1630 const tagged_y = try fromSlice(Tagged, .{
1631 .gpa = gpa,
1632 .source = ".{.@\"y y\" = true}",
1633 .diag = null,
1634 });
1539 try std.testing.expectEqual(Tagged{ .@"y y" = true }, tagged_y);1635 try std.testing.expectEqual(Tagged{ .@"y y" = true }, tagged_y);
1540 const tagged_z_shorthand = try fromSlice(Tagged, gpa, ".z", null, .{});1636 const tagged_z_shorthand = try fromSlice(Tagged, .{
1637 .gpa = gpa,
1638 .source = ".z",
1639 .diag = null,
1640 });
1541 try std.testing.expectEqual(@as(Tagged, .z), tagged_z_shorthand);1641 try std.testing.expectEqual(@as(Tagged, .z), tagged_z_shorthand);
1542 const tagged_zz_shorthand = try fromSlice(Tagged, gpa, ".@\"z z\"", null, .{});1642 const tagged_zz_shorthand = try fromSlice(Tagged, .{
1643 .gpa = gpa,
1644 .source = ".@\"z z\"",
1645 .diag = null,
1646 });
1543 try std.testing.expectEqual(@as(Tagged, .@"z z"), tagged_zz_shorthand);1647 try std.testing.expectEqual(@as(Tagged, .@"z z"), tagged_zz_shorthand);
15441648
1545 const untagged_x = try fromSlice(Untagged, gpa, ".{.x = 1.5}", null, .{});1649 const untagged_x = try fromSlice(Untagged, .{
1650 .gpa = gpa,
1651 .source = ".{.x = 1.5}",
1652 .diag = null,
1653 });
1546 try std.testing.expect(untagged_x.x == 1.5);1654 try std.testing.expect(untagged_x.x == 1.5);
1547 const untagged_y = try fromSlice(Untagged, gpa, ".{.@\"y y\" = true}", null, .{});1655 const untagged_y = try fromSlice(Untagged, .{
1656 .gpa = gpa,
1657 .source = ".{.@\"y y\" = true}",
1658 .diag = null,
1659 });
1548 try std.testing.expect(untagged_y.@"y y");1660 try std.testing.expect(untagged_y.@"y y");
1549 }1661 }
15501662
...@@ -1552,10 +1664,18 @@ test "std.zon unions" {...@@ -1552,10 +1664,18 @@ test "std.zon unions" {
1552 {1664 {
1553 const Union = union(enum) { bar: []const u8, baz: bool };1665 const Union = union(enum) { bar: []const u8, baz: bool };
15541666
1555 const noalloc = try fromSliceAlloc(Union, gpa, ".{.baz = false}", null, .{});1667 const noalloc = try fromSliceAlloc(Union, .{
1668 .gpa = gpa,
1669 .source = ".{.baz = false}",
1670 .diag = null,
1671 });
1556 try std.testing.expectEqual(Union{ .baz = false }, noalloc);1672 try std.testing.expectEqual(Union{ .baz = false }, noalloc);
15571673
1558 const alloc = try fromSliceAlloc(Union, gpa, ".{.bar = \"qux\"}", null, .{});1674 const alloc = try fromSliceAlloc(Union, .{
1675 .gpa = gpa,
1676 .source = ".{.bar = \"qux\"}",
1677 .diag = null,
1678 });
1559 defer free(gpa, alloc);1679 defer free(gpa, alloc);
1560 try std.testing.expectEqualDeep(Union{ .bar = "qux" }, alloc);1680 try std.testing.expectEqualDeep(Union{ .bar = "qux" }, alloc);
1561 }1681 }
...@@ -1567,7 +1687,7 @@ test "std.zon unions" {...@@ -1567,7 +1687,7 @@ test "std.zon unions" {
1567 defer diag.deinit(gpa);1687 defer diag.deinit(gpa);
1568 try std.testing.expectError(1688 try std.testing.expectError(
1569 error.ParseZon,1689 error.ParseZon,
1570 fromSliceAlloc(Union, gpa, ".{.z=2.5}", &diag, .{}),1690 fromSliceAlloc(Union, .{ .gpa = gpa, .source = ".{.z=2.5}", .diag = &diag }),
1571 );1691 );
1572 try std.testing.expectFmt(1692 try std.testing.expectFmt(
1573 \\1:4: error: unexpected field 'z'1693 \\1:4: error: unexpected field 'z'
...@@ -1586,7 +1706,7 @@ test "std.zon unions" {...@@ -1586,7 +1706,7 @@ test "std.zon unions" {
1586 defer diag.deinit(gpa);1706 defer diag.deinit(gpa);
1587 try std.testing.expectError(1707 try std.testing.expectError(
1588 error.ParseZon,1708 error.ParseZon,
1589 fromSliceAlloc(Union, gpa, ".{.x=1}", &diag, .{}),1709 fromSliceAlloc(Union, .{ .gpa = gpa, .source = ".{.x=1}", .diag = &diag }),
1590 );1710 );
1591 try std.testing.expectFmt("1:6: error: expected type 'void'\n", "{f}", .{diag});1711 try std.testing.expectFmt("1:6: error: expected type 'void'\n", "{f}", .{diag});
1592 }1712 }
...@@ -1598,7 +1718,11 @@ test "std.zon unions" {...@@ -1598,7 +1718,11 @@ test "std.zon unions" {
1598 defer diag.deinit(gpa);1718 defer diag.deinit(gpa);
1599 try std.testing.expectError(1719 try std.testing.expectError(
1600 error.ParseZon,1720 error.ParseZon,
1601 fromSliceAlloc(Union, gpa, ".{.x = 1.5, .y = true}", &diag, .{}),1721 fromSliceAlloc(Union, .{
1722 .gpa = gpa,
1723 .source = ".{.x = 1.5, .y = true}",
1724 .diag = &diag,
1725 }),
1602 );1726 );
1603 try std.testing.expectFmt("1:2: error: expected union\n", "{f}", .{diag});1727 try std.testing.expectFmt("1:2: error: expected union\n", "{f}", .{diag});
1604 }1728 }
...@@ -1610,7 +1734,7 @@ test "std.zon unions" {...@@ -1610,7 +1734,7 @@ test "std.zon unions" {
1610 defer diag.deinit(gpa);1734 defer diag.deinit(gpa);
1611 try std.testing.expectError(1735 try std.testing.expectError(
1612 error.ParseZon,1736 error.ParseZon,
1613 fromSliceAlloc(Union, gpa, ".{}", &diag, .{}),1737 fromSliceAlloc(Union, .{ .gpa = gpa, .source = ".{}", .diag = &diag }),
1614 );1738 );
1615 try std.testing.expectFmt("1:2: error: expected union\n", "{f}", .{diag});1739 try std.testing.expectFmt("1:2: error: expected union\n", "{f}", .{diag});
1616 }1740 }
...@@ -1620,7 +1744,11 @@ test "std.zon unions" {...@@ -1620,7 +1744,11 @@ test "std.zon unions" {
1620 const Union = union { x: void };1744 const Union = union { x: void };
1621 var diag: Diagnostics = .{};1745 var diag: Diagnostics = .{};
1622 defer diag.deinit(gpa);1746 defer diag.deinit(gpa);
1623 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Union, gpa, ".x", &diag, .{}));1747 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Union, .{
1748 .gpa = gpa,
1749 .source = ".x",
1750 .diag = &diag,
1751 }));
1624 try std.testing.expectFmt("1:2: error: expected union\n", "{f}", .{diag});1752 try std.testing.expectFmt("1:2: error: expected union\n", "{f}", .{diag});
1625 }1753 }
16261754
...@@ -1629,7 +1757,11 @@ test "std.zon unions" {...@@ -1629,7 +1757,11 @@ test "std.zon unions" {
1629 const Union = union(enum) { x: void };1757 const Union = union(enum) { x: void };
1630 var diag: Diagnostics = .{};1758 var diag: Diagnostics = .{};
1631 defer diag.deinit(gpa);1759 defer diag.deinit(gpa);
1632 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Union, gpa, ".y", &diag, .{}));1760 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Union, .{
1761 .gpa = gpa,
1762 .source = ".y",
1763 .diag = &diag,
1764 }));
1633 try std.testing.expectFmt(1765 try std.testing.expectFmt(
1634 \\1:2: error: unexpected field 'y'1766 \\1:2: error: unexpected field 'y'
1635 \\1:2: note: supported: 'x'1767 \\1:2: note: supported: 'x'
...@@ -1645,7 +1777,11 @@ test "std.zon unions" {...@@ -1645,7 +1777,11 @@ test "std.zon unions" {
1645 const Union = union(enum) { x: f32 };1777 const Union = union(enum) { x: f32 };
1646 var diag: Diagnostics = .{};1778 var diag: Diagnostics = .{};
1647 defer diag.deinit(gpa);1779 defer diag.deinit(gpa);
1648 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Union, gpa, ".x", &diag, .{}));1780 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Union, .{
1781 .gpa = gpa,
1782 .source = ".x",
1783 .diag = &diag,
1784 }));
1649 try std.testing.expectFmt("1:2: error: expected union\n", "{f}", .{diag});1785 try std.testing.expectFmt("1:2: error: expected union\n", "{f}", .{diag});
1650 }1786 }
1651}1787}
...@@ -1660,16 +1796,32 @@ test "std.zon structs" {...@@ -1660,16 +1796,32 @@ test "std.zon structs" {
1660 const Vec2 = struct { x: f32, y: f32 };1796 const Vec2 = struct { x: f32, y: f32 };
1661 const Vec3 = struct { x: f32, y: f32, z: f32 };1797 const Vec3 = struct { x: f32, y: f32, z: f32 };
16621798
1663 const zero = try fromSlice(Vec0, gpa, ".{}", null, .{});1799 const zero = try fromSlice(Vec0, .{
1800 .gpa = gpa,
1801 .source = ".{}",
1802 .diag = null,
1803 });
1664 try std.testing.expectEqual(Vec0{}, zero);1804 try std.testing.expectEqual(Vec0{}, zero);
16651805
1666 const one = try fromSlice(Vec1, gpa, ".{.x = 1.2}", null, .{});1806 const one = try fromSlice(Vec1, .{
1807 .gpa = gpa,
1808 .source = ".{.x = 1.2}",
1809 .diag = null,
1810 });
1667 try std.testing.expectEqual(Vec1{ .x = 1.2 }, one);1811 try std.testing.expectEqual(Vec1{ .x = 1.2 }, one);
16681812
1669 const two = try fromSlice(Vec2, gpa, ".{.x = 1.2, .y = 3.4}", null, .{});1813 const two = try fromSlice(Vec2, .{
1814 .gpa = gpa,
1815 .source = ".{.x = 1.2, .y = 3.4}",
1816 .diag = null,
1817 });
1670 try std.testing.expectEqual(Vec2{ .x = 1.2, .y = 3.4 }, two);1818 try std.testing.expectEqual(Vec2{ .x = 1.2, .y = 3.4 }, two);
16711819
1672 const three = try fromSlice(Vec3, gpa, ".{.x = 1.2, .y = 3.4, .z = 5.6}", null, .{});1820 const three = try fromSlice(Vec3, .{
1821 .gpa = gpa,
1822 .source = ".{.x = 1.2, .y = 3.4, .z = 5.6}",
1823 .diag = null,
1824 });
1673 try std.testing.expectEqual(Vec3{ .x = 1.2, .y = 3.4, .z = 5.6 }, three);1825 try std.testing.expectEqual(Vec3{ .x = 1.2, .y = 3.4, .z = 5.6 }, three);
1674 }1826 }
16751827
...@@ -1677,13 +1829,11 @@ test "std.zon structs" {...@@ -1677,13 +1829,11 @@ test "std.zon structs" {
1677 {1829 {
1678 const Foo = struct { bar: []const u8, baz: []const []const u8 };1830 const Foo = struct { bar: []const u8, baz: []const []const u8 };
16791831
1680 const parsed = try fromSliceAlloc(1832 const parsed = try fromSliceAlloc(Foo, .{
1681 Foo,1833 .gpa = gpa,
1682 gpa,1834 .source = ".{.bar = \"qux\", .baz = .{\"a\", \"b\"}}",
1683 ".{.bar = \"qux\", .baz = .{\"a\", \"b\"}}",1835 .diag = null,
1684 null,1836 });
1685 .{},
1686 );
1687 defer free(gpa, parsed);1837 defer free(gpa, parsed);
1688 try std.testing.expectEqualDeep(Foo{ .bar = "qux", .baz = &.{ "a", "b" } }, parsed);1838 try std.testing.expectEqualDeep(Foo{ .bar = "qux", .baz = &.{ "a", "b" } }, parsed);
1689 }1839 }
...@@ -1695,7 +1845,7 @@ test "std.zon structs" {...@@ -1695,7 +1845,7 @@ test "std.zon structs" {
1695 defer diag.deinit(gpa);1845 defer diag.deinit(gpa);
1696 try std.testing.expectError(1846 try std.testing.expectError(
1697 error.ParseZon,1847 error.ParseZon,
1698 fromSlice(Vec2, gpa, ".{.x=1.5, .z=2.5}", &diag, .{}),1848 fromSlice(Vec2, .{ .gpa = gpa, .source = ".{.x=1.5, .z=2.5}", .diag = &diag }),
1699 );1849 );
1700 try std.testing.expectFmt(1850 try std.testing.expectFmt(
1701 \\1:12: error: unexpected field 'z'1851 \\1:12: error: unexpected field 'z'
...@@ -1714,7 +1864,7 @@ test "std.zon structs" {...@@ -1714,7 +1864,7 @@ test "std.zon structs" {
1714 defer diag.deinit(gpa);1864 defer diag.deinit(gpa);
1715 try std.testing.expectError(1865 try std.testing.expectError(
1716 error.ParseZon,1866 error.ParseZon,
1717 fromSlice(Vec2, gpa, ".{.x=1.5, .x=2.5, .x=3.5}", &diag, .{}),1867 fromSlice(Vec2, .{ .gpa = gpa, .source = ".{.x=1.5, .x=2.5, .x=3.5}", .diag = &diag }),
1718 );1868 );
1719 try std.testing.expectFmt(1869 try std.testing.expectFmt(
1720 \\1:4: error: duplicate struct field name1870 \\1:4: error: duplicate struct field name
...@@ -1726,8 +1876,11 @@ test "std.zon structs" {...@@ -1726,8 +1876,11 @@ test "std.zon structs" {
1726 // Ignore unknown fields1876 // Ignore unknown fields
1727 {1877 {
1728 const Vec2 = struct { x: f32, y: f32 = 2.0 };1878 const Vec2 = struct { x: f32, y: f32 = 2.0 };
1729 const parsed = try fromSlice(Vec2, gpa, ".{ .x = 1.0, .z = 3.0 }", null, .{1879 const parsed = try fromSlice(Vec2, .{
1880 .gpa = gpa,
1881 .source = ".{ .x = 1.0, .z = 3.0 }",
1730 .ignore_unknown_fields = true,1882 .ignore_unknown_fields = true,
1883 .diag = null,
1731 });1884 });
1732 try std.testing.expectEqual(Vec2{ .x = 1.0, .y = 2.0 }, parsed);1885 try std.testing.expectEqual(Vec2{ .x = 1.0, .y = 2.0 }, parsed);
1733 }1886 }
...@@ -1739,7 +1892,7 @@ test "std.zon structs" {...@@ -1739,7 +1892,7 @@ test "std.zon structs" {
1739 defer diag.deinit(gpa);1892 defer diag.deinit(gpa);
1740 try std.testing.expectError(1893 try std.testing.expectError(
1741 error.ParseZon,1894 error.ParseZon,
1742 fromSlice(Vec2, gpa, ".{.x=1.5, .z=2.5}", &diag, .{}),1895 fromSlice(Vec2, .{ .gpa = gpa, .source = ".{.x=1.5, .z=2.5}", .diag = &diag }),
1743 );1896 );
1744 try std.testing.expectFmt(1897 try std.testing.expectFmt(
1745 \\1:4: error: unexpected field 'x'1898 \\1:4: error: unexpected field 'x'
...@@ -1755,7 +1908,7 @@ test "std.zon structs" {...@@ -1755,7 +1908,7 @@ test "std.zon structs" {
1755 defer diag.deinit(gpa);1908 defer diag.deinit(gpa);
1756 try std.testing.expectError(1909 try std.testing.expectError(
1757 error.ParseZon,1910 error.ParseZon,
1758 fromSlice(Vec2, gpa, ".{.x=1.5}", &diag, .{}),1911 fromSlice(Vec2, .{ .gpa = gpa, .source = ".{.x=1.5}", .diag = &diag }),
1759 );1912 );
1760 try std.testing.expectFmt("1:2: error: missing required field y\n", "{f}", .{diag});1913 try std.testing.expectFmt("1:2: error: missing required field y\n", "{f}", .{diag});
1761 }1914 }
...@@ -1763,14 +1916,14 @@ test "std.zon structs" {...@@ -1763,14 +1916,14 @@ test "std.zon structs" {
1763 // Default field1916 // Default field
1764 {1917 {
1765 const Vec2 = struct { x: f32, y: f32 = 1.5 };1918 const Vec2 = struct { x: f32, y: f32 = 1.5 };
1766 const parsed = try fromSlice(Vec2, gpa, ".{.x = 1.2}", null, .{});1919 const parsed = try fromSlice(Vec2, .{ .gpa = gpa, .source = ".{.x = 1.2}", .diag = null });
1767 try std.testing.expectEqual(Vec2{ .x = 1.2, .y = 1.5 }, parsed);1920 try std.testing.expectEqual(Vec2{ .x = 1.2, .y = 1.5 }, parsed);
1768 }1921 }
17691922
1770 // Comptime field1923 // Comptime field
1771 {1924 {
1772 const Vec2 = struct { x: f32, comptime y: f32 = 1.5 };1925 const Vec2 = struct { x: f32, comptime y: f32 = 1.5 };
1773 const parsed = try fromSlice(Vec2, gpa, ".{.x = 1.2}", null, .{});1926 const parsed = try fromSlice(Vec2, .{ .gpa = gpa, .source = ".{.x = 1.2}", .diag = null });
1774 try std.testing.expectEqual(Vec2{ .x = 1.2, .y = 1.5 }, parsed);1927 try std.testing.expectEqual(Vec2{ .x = 1.2, .y = 1.5 }, parsed);
1775 }1928 }
17761929
...@@ -1779,7 +1932,11 @@ test "std.zon structs" {...@@ -1779,7 +1932,11 @@ test "std.zon structs" {
1779 const Vec2 = struct { x: f32, comptime y: f32 = 1.5 };1932 const Vec2 = struct { x: f32, comptime y: f32 = 1.5 };
1780 var diag: Diagnostics = .{};1933 var diag: Diagnostics = .{};
1781 defer diag.deinit(gpa);1934 defer diag.deinit(gpa);
1782 const parsed = fromSlice(Vec2, gpa, ".{.x = 1.2, .y = 1.5}", &diag, .{});1935 const parsed = fromSlice(Vec2, .{
1936 .gpa = gpa,
1937 .source = ".{.x = 1.2, .y = 1.5}",
1938 .diag = &diag,
1939 });
1783 try std.testing.expectError(error.ParseZon, parsed);1940 try std.testing.expectError(error.ParseZon, parsed);
1784 try std.testing.expectFmt(1941 try std.testing.expectFmt(
1785 \\1:18: error: cannot initialize comptime field1942 \\1:18: error: cannot initialize comptime field
...@@ -1791,14 +1948,22 @@ test "std.zon structs" {...@@ -1791,14 +1948,22 @@ test "std.zon structs" {
1791 // incorrect way that broke for enum values)1948 // incorrect way that broke for enum values)
1792 {1949 {
1793 const Vec0 = struct { x: enum { x } };1950 const Vec0 = struct { x: enum { x } };
1794 const parsed = try fromSlice(Vec0, gpa, ".{ .x = .x }", null, .{});1951 const parsed = try fromSlice(Vec0, .{
1952 .gpa = gpa,
1953 .source = ".{ .x = .x }",
1954 .diag = null,
1955 });
1795 try std.testing.expectEqual(Vec0{ .x = .x }, parsed);1956 try std.testing.expectEqual(Vec0{ .x = .x }, parsed);
1796 }1957 }
17971958
1798 // Enum field and struct field with @1959 // Enum field and struct field with @
1799 {1960 {
1800 const Vec0 = struct { @"x x": enum { @"x x" } };1961 const Vec0 = struct { @"x x": enum { @"x x" } };
1801 const parsed = try fromSlice(Vec0, gpa, ".{ .@\"x x\" = .@\"x x\" }", null, .{});1962 const parsed = try fromSlice(Vec0, .{
1963 .gpa = gpa,
1964 .source = ".{ .@\"x x\" = .@\"x x\" }",
1965 .diag = null,
1966 });
1802 try std.testing.expectEqual(Vec0{ .@"x x" = .@"x x" }, parsed);1967 try std.testing.expectEqual(Vec0{ .@"x x" = .@"x x" }, parsed);
1803 }1968 }
18041969
...@@ -1808,7 +1973,11 @@ test "std.zon structs" {...@@ -1808,7 +1973,11 @@ test "std.zon structs" {
1808 {1973 {
1809 var diag: Diagnostics = .{};1974 var diag: Diagnostics = .{};
1810 defer diag.deinit(gpa);1975 defer diag.deinit(gpa);
1811 const parsed = fromSlice(struct {}, gpa, "Empty{}", &diag, .{});1976 const parsed = fromSlice(struct {}, .{
1977 .gpa = gpa,
1978 .source = "Empty{}",
1979 .diag = &diag,
1980 });
1812 try std.testing.expectError(error.ParseZon, parsed);1981 try std.testing.expectError(error.ParseZon, parsed);
1813 try std.testing.expectFmt(1982 try std.testing.expectFmt(
1814 \\1:1: error: types are not available in ZON1983 \\1:1: error: types are not available in ZON
...@@ -1821,7 +1990,11 @@ test "std.zon structs" {...@@ -1821,7 +1990,11 @@ test "std.zon structs" {
1821 {1990 {
1822 var diag: Diagnostics = .{};1991 var diag: Diagnostics = .{};
1823 defer diag.deinit(gpa);1992 defer diag.deinit(gpa);
1824 const parsed = fromSlice([3]u8, gpa, "[3]u8{1, 2, 3}", &diag, .{});1993 const parsed = fromSlice([3]u8, .{
1994 .gpa = gpa,
1995 .source = "[3]u8{1, 2, 3}",
1996 .diag = &diag,
1997 });
1825 try std.testing.expectError(error.ParseZon, parsed);1998 try std.testing.expectError(error.ParseZon, parsed);
1826 try std.testing.expectFmt(1999 try std.testing.expectFmt(
1827 \\1:1: error: types are not available in ZON2000 \\1:1: error: types are not available in ZON
...@@ -1834,7 +2007,11 @@ test "std.zon structs" {...@@ -1834,7 +2007,11 @@ test "std.zon structs" {
1834 {2007 {
1835 var diag: Diagnostics = .{};2008 var diag: Diagnostics = .{};
1836 defer diag.deinit(gpa);2009 defer diag.deinit(gpa);
1837 const parsed = fromSliceAlloc([]u8, gpa, "[]u8{1, 2, 3}", &diag, .{});2010 const parsed = fromSliceAlloc([]u8, .{
2011 .gpa = gpa,
2012 .source = "[]u8{1, 2, 3}",
2013 .diag = &diag,
2014 });
1838 try std.testing.expectError(error.ParseZon, parsed);2015 try std.testing.expectError(error.ParseZon, parsed);
1839 try std.testing.expectFmt(2016 try std.testing.expectFmt(
1840 \\1:1: error: types are not available in ZON2017 \\1:1: error: types are not available in ZON
...@@ -1847,13 +2024,11 @@ test "std.zon structs" {...@@ -1847,13 +2024,11 @@ test "std.zon structs" {
1847 {2024 {
1848 var diag: Diagnostics = .{};2025 var diag: Diagnostics = .{};
1849 defer diag.deinit(gpa);2026 defer diag.deinit(gpa);
1850 const parsed = fromSlice(2027 const parsed = fromSlice(struct { u8, u8, u8 }, .{
1851 struct { u8, u8, u8 },2028 .gpa = gpa,
1852 gpa,2029 .source = "Tuple{1, 2, 3}",
1853 "Tuple{1, 2, 3}",2030 .diag = &diag,
1854 &diag,2031 });
1855 .{},
1856 );
1857 try std.testing.expectError(error.ParseZon, parsed);2032 try std.testing.expectError(error.ParseZon, parsed);
1858 try std.testing.expectFmt(2033 try std.testing.expectFmt(
1859 \\1:1: error: types are not available in ZON2034 \\1:1: error: types are not available in ZON
...@@ -1866,7 +2041,11 @@ test "std.zon structs" {...@@ -1866,7 +2041,11 @@ test "std.zon structs" {
1866 {2041 {
1867 var diag: Diagnostics = .{};2042 var diag: Diagnostics = .{};
1868 defer diag.deinit(gpa);2043 defer diag.deinit(gpa);
1869 const parsed = fromSlice(struct {}, gpa, ".{ .x = Tuple{1, 2, 3} }", &diag, .{});2044 const parsed = fromSlice(struct {}, .{
2045 .gpa = gpa,
2046 .source = ".{ .x = Tuple{1, 2, 3} }",
2047 .diag = &diag,
2048 });
1870 try std.testing.expectError(error.ParseZon, parsed);2049 try std.testing.expectError(error.ParseZon, parsed);
1871 try std.testing.expectFmt(2050 try std.testing.expectFmt(
1872 \\1:9: error: types are not available in ZON2051 \\1:9: error: types are not available in ZON
...@@ -1887,23 +2066,43 @@ test "std.zon tuples" {...@@ -1887,23 +2066,43 @@ test "std.zon tuples" {
1887 const Tuple2 = struct { f32, bool };2066 const Tuple2 = struct { f32, bool };
1888 const Tuple3 = struct { f32, bool, u8 };2067 const Tuple3 = struct { f32, bool, u8 };
18892068
1890 const zero = try fromSlice(Tuple0, gpa, ".{}", null, .{});2069 const zero = try fromSlice(Tuple0, .{
2070 .gpa = gpa,
2071 .source = ".{}",
2072 .diag = null,
2073 });
1891 try std.testing.expectEqual(Tuple0{}, zero);2074 try std.testing.expectEqual(Tuple0{}, zero);
18922075
1893 const one = try fromSlice(Tuple1, gpa, ".{1.2}", null, .{});2076 const one = try fromSlice(Tuple1, .{
2077 .gpa = gpa,
2078 .source = ".{1.2}",
2079 .diag = null,
2080 });
1894 try std.testing.expectEqual(Tuple1{1.2}, one);2081 try std.testing.expectEqual(Tuple1{1.2}, one);
18952082
1896 const two = try fromSlice(Tuple2, gpa, ".{1.2, true}", null, .{});2083 const two = try fromSlice(Tuple2, .{
2084 .gpa = gpa,
2085 .source = ".{1.2, true}",
2086 .diag = null,
2087 });
1897 try std.testing.expectEqual(Tuple2{ 1.2, true }, two);2088 try std.testing.expectEqual(Tuple2{ 1.2, true }, two);
18982089
1899 const three = try fromSlice(Tuple3, gpa, ".{1.2, false, 3}", null, .{});2090 const three = try fromSlice(Tuple3, .{
2091 .gpa = gpa,
2092 .source = ".{1.2, false, 3}",
2093 .diag = null,
2094 });
1900 try std.testing.expectEqual(Tuple3{ 1.2, false, 3 }, three);2095 try std.testing.expectEqual(Tuple3{ 1.2, false, 3 }, three);
1901 }2096 }
19022097
1903 // Deep free2098 // Deep free
1904 {2099 {
1905 const Tuple = struct { []const u8, []const u8 };2100 const Tuple = struct { []const u8, []const u8 };
1906 const parsed = try fromSliceAlloc(Tuple, gpa, ".{\"hello\", \"world\"}", null, .{});2101 const parsed = try fromSliceAlloc(Tuple, .{
2102 .gpa = gpa,
2103 .source = ".{\"hello\", \"world\"}",
2104 .diag = null,
2105 });
1907 defer free(gpa, parsed);2106 defer free(gpa, parsed);
1908 try std.testing.expectEqualDeep(Tuple{ "hello", "world" }, parsed);2107 try std.testing.expectEqualDeep(Tuple{ "hello", "world" }, parsed);
1909 }2108 }
...@@ -1915,7 +2114,7 @@ test "std.zon tuples" {...@@ -1915,7 +2114,7 @@ test "std.zon tuples" {
1915 defer diag.deinit(gpa);2114 defer diag.deinit(gpa);
1916 try std.testing.expectError(2115 try std.testing.expectError(
1917 error.ParseZon,2116 error.ParseZon,
1918 fromSlice(Tuple, gpa, ".{0.5, true, 123}", &diag, .{}),2117 fromSlice(Tuple, .{ .gpa = gpa, .source = ".{0.5, true, 123}", .diag = &diag }),
1919 );2118 );
1920 try std.testing.expectFmt("1:14: error: index 2 outside of tuple length 2\n", "{f}", .{diag});2119 try std.testing.expectFmt("1:14: error: index 2 outside of tuple length 2\n", "{f}", .{diag});
1921 }2120 }
...@@ -1927,7 +2126,7 @@ test "std.zon tuples" {...@@ -1927,7 +2126,7 @@ test "std.zon tuples" {
1927 defer diag.deinit(gpa);2126 defer diag.deinit(gpa);
1928 try std.testing.expectError(2127 try std.testing.expectError(
1929 error.ParseZon,2128 error.ParseZon,
1930 fromSlice(Tuple, gpa, ".{0.5}", &diag, .{}),2129 fromSlice(Tuple, .{ .gpa = gpa, .source = ".{0.5}", .diag = &diag }),
1931 );2130 );
1932 try std.testing.expectFmt(2131 try std.testing.expectFmt(
1933 "1:2: error: missing tuple field with index 1\n",2132 "1:2: error: missing tuple field with index 1\n",
...@@ -1943,7 +2142,7 @@ test "std.zon tuples" {...@@ -1943,7 +2142,7 @@ test "std.zon tuples" {
1943 defer diag.deinit(gpa);2142 defer diag.deinit(gpa);
1944 try std.testing.expectError(2143 try std.testing.expectError(
1945 error.ParseZon,2144 error.ParseZon,
1946 fromSlice(Tuple, gpa, ".{.foo = 10.0}", &diag, .{}),2145 fromSlice(Tuple, .{ .gpa = gpa, .source = ".{.foo = 10.0}", .diag = &diag }),
1947 );2146 );
1948 try std.testing.expectFmt("1:2: error: expected tuple\n", "{f}", .{diag});2147 try std.testing.expectFmt("1:2: error: expected tuple\n", "{f}", .{diag});
1949 }2148 }
...@@ -1955,7 +2154,7 @@ test "std.zon tuples" {...@@ -1955,7 +2154,7 @@ test "std.zon tuples" {
1955 defer diag.deinit(gpa);2154 defer diag.deinit(gpa);
1956 try std.testing.expectError(2155 try std.testing.expectError(
1957 error.ParseZon,2156 error.ParseZon,
1958 fromSlice(Struct, gpa, ".{10.0}", &diag, .{}),2157 fromSlice(Struct, .{ .gpa = gpa, .source = ".{10.0}", .diag = &diag }),
1959 );2158 );
1960 try std.testing.expectFmt("1:2: error: expected struct\n", "{f}", .{diag});2159 try std.testing.expectFmt("1:2: error: expected struct\n", "{f}", .{diag});
1961 }2160 }
...@@ -1963,7 +2162,7 @@ test "std.zon tuples" {...@@ -1963,7 +2162,7 @@ test "std.zon tuples" {
1963 // Comptime field2162 // Comptime field
1964 {2163 {
1965 const Vec2 = struct { f32, comptime f32 = 1.5 };2164 const Vec2 = struct { f32, comptime f32 = 1.5 };
1966 const parsed = try fromSlice(Vec2, gpa, ".{ 1.2 }", null, .{});2165 const parsed = try fromSlice(Vec2, .{ .gpa = gpa, .source = ".{ 1.2 }", .diag = null });
1967 try std.testing.expectEqual(Vec2{ 1.2, 1.5 }, parsed);2166 try std.testing.expectEqual(Vec2{ 1.2, 1.5 }, parsed);
1968 }2167 }
19692168
...@@ -1972,7 +2171,7 @@ test "std.zon tuples" {...@@ -1972,7 +2171,7 @@ test "std.zon tuples" {
1972 const Vec2 = struct { f32, comptime f32 = 1.5 };2171 const Vec2 = struct { f32, comptime f32 = 1.5 };
1973 var diag: Diagnostics = .{};2172 var diag: Diagnostics = .{};
1974 defer diag.deinit(gpa);2173 defer diag.deinit(gpa);
1975 const parsed = fromSlice(Vec2, gpa, ".{ 1.2, 1.5}", &diag, .{});2174 const parsed = fromSlice(Vec2, .{ .gpa = gpa, .source = ".{ 1.2, 1.5}", .diag = &diag });
1976 try std.testing.expectError(error.ParseZon, parsed);2175 try std.testing.expectError(error.ParseZon, parsed);
1977 try std.testing.expectFmt(2176 try std.testing.expectFmt(
1978 \\1:9: error: cannot initialize comptime field2177 \\1:9: error: cannot initialize comptime field
...@@ -1989,49 +2188,97 @@ test "std.zon arrays and slices" {...@@ -1989,49 +2188,97 @@ test "std.zon arrays and slices" {
1989 {2188 {
1990 // Arrays2189 // Arrays
1991 {2190 {
1992 const zero = try fromSlice([0]u8, gpa, ".{}", null, .{});2191 const zero = try fromSlice([0]u8, .{
2192 .gpa = gpa,
2193 .source = ".{}",
2194 .diag = null,
2195 });
1993 try std.testing.expectEqualSlices(u8, &@as([0]u8, .{}), &zero);2196 try std.testing.expectEqualSlices(u8, &@as([0]u8, .{}), &zero);
19942197
1995 const one = try fromSlice([1]u8, gpa, ".{'a'}", null, .{});2198 const one = try fromSlice([1]u8, .{
2199 .gpa = gpa,
2200 .source = ".{'a'}",
2201 .diag = null,
2202 });
1996 try std.testing.expectEqualSlices(u8, &@as([1]u8, .{'a'}), &one);2203 try std.testing.expectEqualSlices(u8, &@as([1]u8, .{'a'}), &one);
19972204
1998 const two = try fromSlice([2]u8, gpa, ".{'a', 'b'}", null, .{});2205 const two = try fromSlice([2]u8, .{
2206 .gpa = gpa,
2207 .source = ".{'a', 'b'}",
2208 .diag = null,
2209 });
1999 try std.testing.expectEqualSlices(u8, &@as([2]u8, .{ 'a', 'b' }), &two);2210 try std.testing.expectEqualSlices(u8, &@as([2]u8, .{ 'a', 'b' }), &two);
20002211
2001 const two_comma = try fromSlice([2]u8, gpa, ".{'a', 'b',}", null, .{});2212 const two_comma = try fromSlice([2]u8, .{
2213 .gpa = gpa,
2214 .source = ".{'a', 'b',}",
2215 .diag = null,
2216 });
2002 try std.testing.expectEqualSlices(u8, &@as([2]u8, .{ 'a', 'b' }), &two_comma);2217 try std.testing.expectEqualSlices(u8, &@as([2]u8, .{ 'a', 'b' }), &two_comma);
20032218
2004 const three = try fromSlice([3]u8, gpa, ".{'a', 'b', 'c'}", null, .{});2219 const three = try fromSlice([3]u8, .{
2220 .gpa = gpa,
2221 .source = ".{'a', 'b', 'c'}",
2222 .diag = null,
2223 });
2005 try std.testing.expectEqualSlices(u8, &.{ 'a', 'b', 'c' }, &three);2224 try std.testing.expectEqualSlices(u8, &.{ 'a', 'b', 'c' }, &three);
20062225
2007 const sentinel = try fromSlice([3:'z']u8, gpa, ".{'a', 'b', 'c'}", null, .{});2226 const sentinel = try fromSlice([3:'z']u8, .{
2227 .gpa = gpa,
2228 .source = ".{'a', 'b', 'c'}",
2229 .diag = null,
2230 });
2008 const expected_sentinel: [3:'z']u8 = .{ 'a', 'b', 'c' };2231 const expected_sentinel: [3:'z']u8 = .{ 'a', 'b', 'c' };
2009 try std.testing.expectEqualSlices(u8, &expected_sentinel, &sentinel);2232 try std.testing.expectEqualSlices(u8, &expected_sentinel, &sentinel);
2010 }2233 }
20112234
2012 // Slice literals2235 // Slice literals
2013 {2236 {
2014 const zero = try fromSliceAlloc([]const u8, gpa, ".{}", null, .{});2237 const zero = try fromSliceAlloc([]const u8, .{
2238 .gpa = gpa,
2239 .source = ".{}",
2240 .diag = null,
2241 });
2015 defer free(gpa, zero);2242 defer free(gpa, zero);
2016 try std.testing.expectEqualSlices(u8, @as([]const u8, &.{}), zero);2243 try std.testing.expectEqualSlices(u8, @as([]const u8, &.{}), zero);
20172244
2018 const one = try fromSliceAlloc([]u8, gpa, ".{'a'}", null, .{});2245 const one = try fromSliceAlloc([]u8, .{
2246 .gpa = gpa,
2247 .source = ".{'a'}",
2248 .diag = null,
2249 });
2019 defer free(gpa, one);2250 defer free(gpa, one);
2020 try std.testing.expectEqualSlices(u8, &.{'a'}, one);2251 try std.testing.expectEqualSlices(u8, &.{'a'}, one);
20212252
2022 const two = try fromSliceAlloc([]const u8, gpa, ".{'a', 'b'}", null, .{});2253 const two = try fromSliceAlloc([]const u8, .{
2254 .gpa = gpa,
2255 .source = ".{'a', 'b'}",
2256 .diag = null,
2257 });
2023 defer free(gpa, two);2258 defer free(gpa, two);
2024 try std.testing.expectEqualSlices(u8, &.{ 'a', 'b' }, two);2259 try std.testing.expectEqualSlices(u8, &.{ 'a', 'b' }, two);
20252260
2026 const two_comma = try fromSliceAlloc([]const u8, gpa, ".{'a', 'b',}", null, .{});2261 const two_comma = try fromSliceAlloc([]const u8, .{
2262 .gpa = gpa,
2263 .source = ".{'a', 'b',}",
2264 .diag = null,
2265 });
2027 defer free(gpa, two_comma);2266 defer free(gpa, two_comma);
2028 try std.testing.expectEqualSlices(u8, &.{ 'a', 'b' }, two_comma);2267 try std.testing.expectEqualSlices(u8, &.{ 'a', 'b' }, two_comma);
20292268
2030 const three = try fromSliceAlloc([]u8, gpa, ".{'a', 'b', 'c'}", null, .{});2269 const three = try fromSliceAlloc([]u8, .{
2270 .gpa = gpa,
2271 .source = ".{'a', 'b', 'c'}",
2272 .diag = null,
2273 });
2031 defer free(gpa, three);2274 defer free(gpa, three);
2032 try std.testing.expectEqualSlices(u8, &.{ 'a', 'b', 'c' }, three);2275 try std.testing.expectEqualSlices(u8, &.{ 'a', 'b', 'c' }, three);
20332276
2034 const sentinel = try fromSliceAlloc([:'z']const u8, gpa, ".{'a', 'b', 'c'}", null, .{});2277 const sentinel = try fromSliceAlloc([:'z']const u8, .{
2278 .gpa = gpa,
2279 .source = ".{'a', 'b', 'c'}",
2280 .diag = null,
2281 });
2035 defer free(gpa, sentinel);2282 defer free(gpa, sentinel);
2036 const expected_sentinel: [:'z']const u8 = &.{ 'a', 'b', 'c' };2283 const expected_sentinel: [:'z']const u8 = &.{ 'a', 'b', 'c' };
2037 try std.testing.expectEqualSlices(u8, expected_sentinel, sentinel);2284 try std.testing.expectEqualSlices(u8, expected_sentinel, sentinel);
...@@ -2042,7 +2289,11 @@ test "std.zon arrays and slices" {...@@ -2042,7 +2289,11 @@ test "std.zon arrays and slices" {
2042 {2289 {
2043 // Arrays2290 // Arrays
2044 {2291 {
2045 const parsed = try fromSliceAlloc([1][]const u8, gpa, ".{\"abc\"}", null, .{});2292 const parsed = try fromSliceAlloc([1][]const u8, .{
2293 .gpa = gpa,
2294 .source = ".{\"abc\"}",
2295 .diag = null,
2296 });
2046 defer free(gpa, parsed);2297 defer free(gpa, parsed);
2047 const expected: [1][]const u8 = .{"abc"};2298 const expected: [1][]const u8 = .{"abc"};
2048 try std.testing.expectEqualDeep(expected, parsed);2299 try std.testing.expectEqualDeep(expected, parsed);
...@@ -2050,7 +2301,11 @@ test "std.zon arrays and slices" {...@@ -2050,7 +2301,11 @@ test "std.zon arrays and slices" {
20502301
2051 // Slice literals2302 // Slice literals
2052 {2303 {
2053 const parsed = try fromSliceAlloc([]const []const u8, gpa, ".{\"abc\"}", null, .{});2304 const parsed = try fromSliceAlloc([]const []const u8, .{
2305 .gpa = gpa,
2306 .source = ".{\"abc\"}",
2307 .diag = null,
2308 });
2054 defer free(gpa, parsed);2309 defer free(gpa, parsed);
2055 const expected: []const []const u8 = &.{"abc"};2310 const expected: []const []const u8 = &.{"abc"};
2056 try std.testing.expectEqualDeep(expected, parsed);2311 try std.testing.expectEqualDeep(expected, parsed);
...@@ -2061,7 +2316,11 @@ test "std.zon arrays and slices" {...@@ -2061,7 +2316,11 @@ test "std.zon arrays and slices" {
2061 {2316 {
2062 // Arrays2317 // Arrays
2063 {2318 {
2064 const sentinel = try fromSlice([1:2]u8, gpa, ".{1}", null, .{});2319 const sentinel = try fromSlice([1:2]u8, .{
2320 .gpa = gpa,
2321 .source = ".{1}",
2322 .diag = null,
2323 });
2065 try std.testing.expectEqual(@as(usize, 1), sentinel.len);2324 try std.testing.expectEqual(@as(usize, 1), sentinel.len);
2066 try std.testing.expectEqual(@as(u8, 1), sentinel[0]);2325 try std.testing.expectEqual(@as(u8, 1), sentinel[0]);
2067 try std.testing.expectEqual(@as(u8, 2), sentinel[1]);2326 try std.testing.expectEqual(@as(u8, 2), sentinel[1]);
...@@ -2069,7 +2328,11 @@ test "std.zon arrays and slices" {...@@ -2069,7 +2328,11 @@ test "std.zon arrays and slices" {
20692328
2070 // Slice literals2329 // Slice literals
2071 {2330 {
2072 const sentinel = try fromSliceAlloc([:2]align(4) u8, gpa, ".{1}", null, .{});2331 const sentinel = try fromSliceAlloc([:2]align(4) u8, .{
2332 .gpa = gpa,
2333 .source = ".{1}",
2334 .diag = null,
2335 });
2073 defer free(gpa, sentinel);2336 defer free(gpa, sentinel);
2074 try std.testing.expectEqual(@as(usize, 1), sentinel.len);2337 try std.testing.expectEqual(@as(usize, 1), sentinel.len);
2075 try std.testing.expectEqual(@as(u8, 1), sentinel[0]);2338 try std.testing.expectEqual(@as(u8, 1), sentinel[0]);
...@@ -2083,7 +2346,7 @@ test "std.zon arrays and slices" {...@@ -2083,7 +2346,7 @@ test "std.zon arrays and slices" {
2083 defer diag.deinit(gpa);2346 defer diag.deinit(gpa);
2084 try std.testing.expectError(2347 try std.testing.expectError(
2085 error.ParseZon,2348 error.ParseZon,
2086 fromSlice([0]u8, gpa, ".{'a', 'b', 'c'}", &diag, .{}),2349 fromSlice([0]u8, .{ .gpa = gpa, .source = ".{'a', 'b', 'c'}", .diag = &diag }),
2087 );2350 );
2088 try std.testing.expectFmt(2351 try std.testing.expectFmt(
2089 "1:3: error: index 0 outside of array of length 0\n",2352 "1:3: error: index 0 outside of array of length 0\n",
...@@ -2098,7 +2361,7 @@ test "std.zon arrays and slices" {...@@ -2098,7 +2361,7 @@ test "std.zon arrays and slices" {
2098 defer diag.deinit(gpa);2361 defer diag.deinit(gpa);
2099 try std.testing.expectError(2362 try std.testing.expectError(
2100 error.ParseZon,2363 error.ParseZon,
2101 fromSlice([1]u8, gpa, ".{'a', 'b'}", &diag, .{}),2364 fromSlice([1]u8, .{ .gpa = gpa, .source = ".{'a', 'b'}", .diag = &diag }),
2102 );2365 );
2103 try std.testing.expectFmt(2366 try std.testing.expectFmt(
2104 "1:8: error: index 1 outside of array of length 1\n",2367 "1:8: error: index 1 outside of array of length 1\n",
...@@ -2113,7 +2376,7 @@ test "std.zon arrays and slices" {...@@ -2113,7 +2376,7 @@ test "std.zon arrays and slices" {
2113 defer diag.deinit(gpa);2376 defer diag.deinit(gpa);
2114 try std.testing.expectError(2377 try std.testing.expectError(
2115 error.ParseZon,2378 error.ParseZon,
2116 fromSlice([2]u8, gpa, ".{'a'}", &diag, .{}),2379 fromSlice([2]u8, .{ .gpa = gpa, .source = ".{'a'}", .diag = &diag }),
2117 );2380 );
2118 try std.testing.expectFmt(2381 try std.testing.expectFmt(
2119 "1:2: error: expected 2 array elements; found 1\n",2382 "1:2: error: expected 2 array elements; found 1\n",
...@@ -2128,7 +2391,7 @@ test "std.zon arrays and slices" {...@@ -2128,7 +2391,7 @@ test "std.zon arrays and slices" {
2128 defer diag.deinit(gpa);2391 defer diag.deinit(gpa);
2129 try std.testing.expectError(2392 try std.testing.expectError(
2130 error.ParseZon,2393 error.ParseZon,
2131 fromSlice([3]u8, gpa, ".{}", &diag, .{}),2394 fromSlice([3]u8, .{ .gpa = gpa, .source = ".{}", .diag = &diag }),
2132 );2395 );
2133 try std.testing.expectFmt(2396 try std.testing.expectFmt(
2134 "1:2: error: expected 3 array elements; found 0\n",2397 "1:2: error: expected 3 array elements; found 0\n",
...@@ -2145,7 +2408,7 @@ test "std.zon arrays and slices" {...@@ -2145,7 +2408,7 @@ test "std.zon arrays and slices" {
2145 defer diag.deinit(gpa);2408 defer diag.deinit(gpa);
2146 try std.testing.expectError(2409 try std.testing.expectError(
2147 error.ParseZon,2410 error.ParseZon,
2148 fromSlice([3]bool, gpa, ".{'a', 'b', 'c'}", &diag, .{}),2411 fromSlice([3]bool, .{ .gpa = gpa, .source = ".{'a', 'b', 'c'}", .diag = &diag }),
2149 );2412 );
2150 try std.testing.expectFmt("1:3: error: expected type 'bool'\n", "{f}", .{diag});2413 try std.testing.expectFmt("1:3: error: expected type 'bool'\n", "{f}", .{diag});
2151 }2414 }
...@@ -2156,7 +2419,11 @@ test "std.zon arrays and slices" {...@@ -2156,7 +2419,11 @@ test "std.zon arrays and slices" {
2156 defer diag.deinit(gpa);2419 defer diag.deinit(gpa);
2157 try std.testing.expectError(2420 try std.testing.expectError(
2158 error.ParseZon,2421 error.ParseZon,
2159 fromSliceAlloc([]bool, gpa, ".{'a', 'b', 'c'}", &diag, .{}),2422 fromSliceAlloc([]bool, .{
2423 .gpa = gpa,
2424 .source = ".{'a', 'b', 'c'}",
2425 .diag = &diag,
2426 }),
2160 );2427 );
2161 try std.testing.expectFmt("1:3: error: expected type 'bool'\n", "{f}", .{diag});2428 try std.testing.expectFmt("1:3: error: expected type 'bool'\n", "{f}", .{diag});
2162 }2429 }
...@@ -2170,7 +2437,7 @@ test "std.zon arrays and slices" {...@@ -2170,7 +2437,7 @@ test "std.zon arrays and slices" {
2170 defer diag.deinit(gpa);2437 defer diag.deinit(gpa);
2171 try std.testing.expectError(2438 try std.testing.expectError(
2172 error.ParseZon,2439 error.ParseZon,
2173 fromSlice([3]u8, gpa, "'a'", &diag, .{}),2440 fromSlice([3]u8, .{ .gpa = gpa, .source = "'a'", .diag = &diag }),
2174 );2441 );
2175 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});2442 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});
2176 }2443 }
...@@ -2181,7 +2448,7 @@ test "std.zon arrays and slices" {...@@ -2181,7 +2448,7 @@ test "std.zon arrays and slices" {
2181 defer diag.deinit(gpa);2448 defer diag.deinit(gpa);
2182 try std.testing.expectError(2449 try std.testing.expectError(
2183 error.ParseZon,2450 error.ParseZon,
2184 fromSliceAlloc([]u8, gpa, "'a'", &diag, .{}),2451 fromSliceAlloc([]u8, .{ .gpa = gpa, .source = "'a'", .diag = &diag }),
2185 );2452 );
2186 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});2453 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});
2187 }2454 }
...@@ -2193,7 +2460,7 @@ test "std.zon arrays and slices" {...@@ -2193,7 +2460,7 @@ test "std.zon arrays and slices" {
2193 defer diag.deinit(gpa);2460 defer diag.deinit(gpa);
2194 try std.testing.expectError(2461 try std.testing.expectError(
2195 error.ParseZon,2462 error.ParseZon,
2196 fromSliceAlloc([]u8, gpa, " &.{'a', 'b', 'c'}", &diag, .{}),2463 fromSliceAlloc([]u8, .{ .gpa = gpa, .source = " &.{'a', 'b', 'c'}", .diag = &diag }),
2197 );2464 );
2198 try std.testing.expectFmt(2465 try std.testing.expectFmt(
2199 "1:3: error: pointers are not available in ZON\n",2466 "1:3: error: pointers are not available in ZON\n",
...@@ -2208,21 +2475,33 @@ test "std.zon string literal" {...@@ -2208,21 +2475,33 @@ test "std.zon string literal" {
22082475
2209 // Basic string literal2476 // Basic string literal
2210 {2477 {
2211 const parsed = try fromSliceAlloc([]const u8, gpa, "\"abc\"", null, .{});2478 const parsed = try fromSliceAlloc([]const u8, .{
2479 .gpa = gpa,
2480 .source = "\"abc\"",
2481 .diag = null,
2482 });
2212 defer free(gpa, parsed);2483 defer free(gpa, parsed);
2213 try std.testing.expectEqualStrings(@as([]const u8, "abc"), parsed);2484 try std.testing.expectEqualStrings(@as([]const u8, "abc"), parsed);
2214 }2485 }
22152486
2216 // String literal with escape characters2487 // String literal with escape characters
2217 {2488 {
2218 const parsed = try fromSliceAlloc([]const u8, gpa, "\"ab\\nc\"", null, .{});2489 const parsed = try fromSliceAlloc([]const u8, .{
2490 .gpa = gpa,
2491 .source = "\"ab\\nc\"",
2492 .diag = null,
2493 });
2219 defer free(gpa, parsed);2494 defer free(gpa, parsed);
2220 try std.testing.expectEqualStrings(@as([]const u8, "ab\nc"), parsed);2495 try std.testing.expectEqualStrings(@as([]const u8, "ab\nc"), parsed);
2221 }2496 }
22222497
2223 // String literal with embedded null2498 // String literal with embedded null
2224 {2499 {
2225 const parsed = try fromSliceAlloc([]const u8, gpa, "\"ab\\x00c\"", null, .{});2500 const parsed = try fromSliceAlloc([]const u8, .{
2501 .gpa = gpa,
2502 .source = "\"ab\\x00c\"",
2503 .diag = null,
2504 });
2226 defer free(gpa, parsed);2505 defer free(gpa, parsed);
2227 try std.testing.expectEqualStrings(@as([]const u8, "ab\x00c"), parsed);2506 try std.testing.expectEqualStrings(@as([]const u8, "ab\x00c"), parsed);
2228 }2507 }
...@@ -2234,7 +2513,7 @@ test "std.zon string literal" {...@@ -2234,7 +2513,7 @@ test "std.zon string literal" {
2234 defer diag.deinit(gpa);2513 defer diag.deinit(gpa);
2235 try std.testing.expectError(2514 try std.testing.expectError(
2236 error.ParseZon,2515 error.ParseZon,
2237 fromSliceAlloc([]u8, gpa, "\"abcd\"", &diag, .{}),2516 fromSliceAlloc([]u8, .{ .gpa = gpa, .source = "\"abcd\"", .diag = &diag }),
2238 );2517 );
2239 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});2518 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});
2240 }2519 }
...@@ -2244,7 +2523,7 @@ test "std.zon string literal" {...@@ -2244,7 +2523,7 @@ test "std.zon string literal" {
2244 defer diag.deinit(gpa);2523 defer diag.deinit(gpa);
2245 try std.testing.expectError(2524 try std.testing.expectError(
2246 error.ParseZon,2525 error.ParseZon,
2247 fromSliceAlloc([]u8, gpa, "\\\\abcd", &diag, .{}),2526 fromSliceAlloc([]u8, .{ .gpa = gpa, .source = "\\\\abcd", .diag = &diag }),
2248 );2527 );
2249 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});2528 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});
2250 }2529 }
...@@ -2261,7 +2540,7 @@ test "std.zon string literal" {...@@ -2261,7 +2540,7 @@ test "std.zon string literal" {
2261 defer diag.deinit(gpa);2540 defer diag.deinit(gpa);
2262 try std.testing.expectError(2541 try std.testing.expectError(
2263 error.ParseZon,2542 error.ParseZon,
2264 fromSlice([4:0]u8, gpa, "\"abcd\"", &diag, .{}),2543 fromSlice([4:0]u8, .{ .gpa = gpa, .source = "\"abcd\"", .diag = &diag }),
2265 );2544 );
2266 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});2545 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});
2267 }2546 }
...@@ -2271,7 +2550,7 @@ test "std.zon string literal" {...@@ -2271,7 +2550,7 @@ test "std.zon string literal" {
2271 defer diag.deinit(gpa);2550 defer diag.deinit(gpa);
2272 try std.testing.expectError(2551 try std.testing.expectError(
2273 error.ParseZon,2552 error.ParseZon,
2274 fromSlice([4:0]u8, gpa, "\\\\abcd", &diag, .{}),2553 fromSlice([4:0]u8, .{ .gpa = gpa, .source = "\\\\abcd", .diag = &diag }),
2275 );2554 );
2276 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});2555 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});
2277 }2556 }
...@@ -2280,26 +2559,22 @@ test "std.zon string literal" {...@@ -2280,26 +2559,22 @@ test "std.zon string literal" {
2280 // Zero terminated slices2559 // Zero terminated slices
2281 {2560 {
2282 {2561 {
2283 const parsed: [:0]const u8 = try fromSliceAlloc(2562 const parsed: [:0]const u8 = try fromSliceAlloc([:0]const u8, .{
2284 [:0]const u8,2563 .gpa = gpa,
2285 gpa,2564 .source = "\"abc\"",
2286 "\"abc\"",2565 .diag = null,
2287 null,2566 });
2288 .{},
2289 );
2290 defer free(gpa, parsed);2567 defer free(gpa, parsed);
2291 try std.testing.expectEqualStrings("abc", parsed);2568 try std.testing.expectEqualStrings("abc", parsed);
2292 try std.testing.expectEqual(@as(u8, 0), parsed[3]);2569 try std.testing.expectEqual(@as(u8, 0), parsed[3]);
2293 }2570 }
22942571
2295 {2572 {
2296 const parsed: [:0]const u8 = try fromSliceAlloc(2573 const parsed: [:0]const u8 = try fromSliceAlloc([:0]const u8, .{
2297 [:0]const u8,2574 .gpa = gpa,
2298 gpa,2575 .source = "\\\\abc",
2299 "\\\\abc",2576 .diag = null,
2300 null,2577 });
2301 .{},
2302 );
2303 defer free(gpa, parsed);2578 defer free(gpa, parsed);
2304 try std.testing.expectEqualStrings("abc", parsed);2579 try std.testing.expectEqualStrings("abc", parsed);
2305 try std.testing.expectEqual(@as(u8, 0), parsed[3]);2580 try std.testing.expectEqual(@as(u8, 0), parsed[3]);
...@@ -2313,7 +2588,7 @@ test "std.zon string literal" {...@@ -2313,7 +2588,7 @@ test "std.zon string literal" {
2313 defer diag.deinit(gpa);2588 defer diag.deinit(gpa);
2314 try std.testing.expectError(2589 try std.testing.expectError(
2315 error.ParseZon,2590 error.ParseZon,
2316 fromSliceAlloc([:1]const u8, gpa, "\"foo\"", &diag, .{}),2591 fromSliceAlloc([:1]const u8, .{ .gpa = gpa, .source = "\"foo\"", .diag = &diag }),
2317 );2592 );
2318 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});2593 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});
2319 }2594 }
...@@ -2323,7 +2598,7 @@ test "std.zon string literal" {...@@ -2323,7 +2598,7 @@ test "std.zon string literal" {
2323 defer diag.deinit(gpa);2598 defer diag.deinit(gpa);
2324 try std.testing.expectError(2599 try std.testing.expectError(
2325 error.ParseZon,2600 error.ParseZon,
2326 fromSliceAlloc([:1]const u8, gpa, "\\\\foo", &diag, .{}),2601 fromSliceAlloc([:1]const u8, .{ .gpa = gpa, .source = "\\\\foo", .diag = &diag }),
2327 );2602 );
2328 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});2603 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});
2329 }2604 }
...@@ -2335,7 +2610,7 @@ test "std.zon string literal" {...@@ -2335,7 +2610,7 @@ test "std.zon string literal" {
2335 defer diag.deinit(gpa);2610 defer diag.deinit(gpa);
2336 try std.testing.expectError(2611 try std.testing.expectError(
2337 error.ParseZon,2612 error.ParseZon,
2338 fromSliceAlloc([]const u8, gpa, "true", &diag, .{}),2613 fromSliceAlloc([]const u8, .{ .gpa = gpa, .source = "true", .diag = &diag }),
2339 );2614 );
2340 try std.testing.expectFmt("1:1: error: expected string\n", "{f}", .{diag});2615 try std.testing.expectFmt("1:1: error: expected string\n", "{f}", .{diag});
2341 }2616 }
...@@ -2346,7 +2621,7 @@ test "std.zon string literal" {...@@ -2346,7 +2621,7 @@ test "std.zon string literal" {
2346 defer diag.deinit(gpa);2621 defer diag.deinit(gpa);
2347 try std.testing.expectError(2622 try std.testing.expectError(
2348 error.ParseZon,2623 error.ParseZon,
2349 fromSliceAlloc([]const u8, gpa, ".{false}", &diag, .{}),2624 fromSliceAlloc([]const u8, .{ .gpa = gpa, .source = ".{false}", .diag = &diag }),
2350 );2625 );
2351 try std.testing.expectFmt("1:3: error: expected type 'u8'\n", "{f}", .{diag});2626 try std.testing.expectFmt("1:3: error: expected type 'u8'\n", "{f}", .{diag});
2352 }2627 }
...@@ -2357,7 +2632,7 @@ test "std.zon string literal" {...@@ -2357,7 +2632,7 @@ test "std.zon string literal" {
2357 defer diag.deinit(gpa);2632 defer diag.deinit(gpa);
2358 try std.testing.expectError(2633 try std.testing.expectError(
2359 error.ParseZon,2634 error.ParseZon,
2360 fromSliceAlloc([]const i8, gpa, "\"\\a\"", &diag, .{}),2635 fromSliceAlloc([]const i8, .{ .gpa = gpa, .source = "\"\\a\"", .diag = &diag }),
2361 );2636 );
2362 try std.testing.expectFmt("1:3: error: invalid escape character: 'a'\n", "{f}", .{diag});2637 try std.testing.expectFmt("1:3: error: invalid escape character: 'a'\n", "{f}", .{diag});
2363 }2638 }
...@@ -2369,7 +2644,7 @@ test "std.zon string literal" {...@@ -2369,7 +2644,7 @@ test "std.zon string literal" {
2369 defer diag.deinit(gpa);2644 defer diag.deinit(gpa);
2370 try std.testing.expectError(2645 try std.testing.expectError(
2371 error.ParseZon,2646 error.ParseZon,
2372 fromSliceAlloc([]const i8, gpa, "\"a\"", &diag, .{}),2647 fromSliceAlloc([]const i8, .{ .gpa = gpa, .source = "\"a\"", .diag = &diag }),
2373 );2648 );
2374 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});2649 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});
2375 }2650 }
...@@ -2379,7 +2654,7 @@ test "std.zon string literal" {...@@ -2379,7 +2654,7 @@ test "std.zon string literal" {
2379 defer diag.deinit(gpa);2654 defer diag.deinit(gpa);
2380 try std.testing.expectError(2655 try std.testing.expectError(
2381 error.ParseZon,2656 error.ParseZon,
2382 fromSliceAlloc([]const i8, gpa, "\\\\a", &diag, .{}),2657 fromSliceAlloc([]const i8, .{ .gpa = gpa, .source = "\\\\a", .diag = &diag }),
2383 );2658 );
2384 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});2659 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});
2385 }2660 }
...@@ -2392,7 +2667,11 @@ test "std.zon string literal" {...@@ -2392,7 +2667,11 @@ test "std.zon string literal" {
2392 defer diag.deinit(gpa);2667 defer diag.deinit(gpa);
2393 try std.testing.expectError(2668 try std.testing.expectError(
2394 error.ParseZon,2669 error.ParseZon,
2395 fromSliceAlloc([]align(2) const u8, gpa, "\"abc\"", &diag, .{}),2670 fromSliceAlloc([]align(2) const u8, .{
2671 .gpa = gpa,
2672 .source = "\"abc\"",
2673 .diag = &diag,
2674 }),
2396 );2675 );
2397 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});2676 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});
2398 }2677 }
...@@ -2402,7 +2681,11 @@ test "std.zon string literal" {...@@ -2402,7 +2681,11 @@ test "std.zon string literal" {
2402 defer diag.deinit(gpa);2681 defer diag.deinit(gpa);
2403 try std.testing.expectError(2682 try std.testing.expectError(
2404 error.ParseZon,2683 error.ParseZon,
2405 fromSliceAlloc([]align(2) const u8, gpa, "\\\\abc", &diag, .{}),2684 fromSliceAlloc([]align(2) const u8, .{
2685 .gpa = gpa,
2686 .source = "\\\\abc",
2687 .diag = &diag,
2688 }),
2406 );2689 );
2407 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});2690 try std.testing.expectFmt("1:1: error: expected array\n", "{f}", .{diag});
2408 }2691 }
...@@ -2417,7 +2700,9 @@ test "std.zon string literal" {...@@ -2417,7 +2700,9 @@ test "std.zon string literal" {
2417 message2: String,2700 message2: String,
2418 message3: String,2701 message3: String,
2419 };2702 };
2420 const parsed = try fromSliceAlloc(S, gpa,2703 const parsed = try fromSliceAlloc(S, .{
2704 .gpa = gpa,
2705 .source =
2421 \\.{2706 \\.{
2422 \\ .message =2707 \\ .message =
2423 \\ \\hello, world!2708 \\ \\hello, world!
...@@ -2434,7 +2719,9 @@ test "std.zon string literal" {...@@ -2434,7 +2719,9 @@ test "std.zon string literal" {
2434 \\ \\2719 \\ \\
2435 \\ \\and this.2720 \\ \\and this.
2436 \\}2721 \\}
2437 , null, .{});2722 ,
2723 .diag = null,
2724 });
2438 defer free(gpa, parsed);2725 defer free(gpa, parsed);
2439 try std.testing.expectEqualStrings(2726 try std.testing.expectEqualStrings(
2440 "hello, world!\nthis is a multiline string!\n\n...",2727 "hello, world!\nthis is a multiline string!\n\n...",
...@@ -2457,12 +2744,24 @@ test "std.zon enum literals" {...@@ -2457,12 +2744,24 @@ test "std.zon enum literals" {
2457 };2744 };
24582745
2459 // Tags that exist2746 // Tags that exist
2460 try std.testing.expectEqual(Enum.foo, try fromSlice(Enum, gpa, ".foo", null, .{}));2747 try std.testing.expectEqual(Enum.foo, try fromSlice(Enum, .{
2461 try std.testing.expectEqual(Enum.bar, try fromSlice(Enum, gpa, ".bar", null, .{}));2748 .gpa = gpa,
2462 try std.testing.expectEqual(Enum.baz, try fromSlice(Enum, gpa, ".baz", null, .{}));2749 .source = ".foo",
2750 .diag = null,
2751 }));
2752 try std.testing.expectEqual(Enum.bar, try fromSlice(Enum, .{
2753 .gpa = gpa,
2754 .source = ".bar",
2755 .diag = null,
2756 }));
2757 try std.testing.expectEqual(Enum.baz, try fromSlice(Enum, .{
2758 .gpa = gpa,
2759 .source = ".baz",
2760 .diag = null,
2761 }));
2463 try std.testing.expectEqual(2762 try std.testing.expectEqual(
2464 Enum.@"ab\nc",2763 Enum.@"ab\nc",
2465 try fromSlice(Enum, gpa, ".@\"ab\\nc\"", null, .{}),2764 try fromSlice(Enum, .{ .gpa = gpa, .source = ".@\"ab\\nc\"", .diag = null }),
2466 );2765 );
24672766
2468 // Bad tag2767 // Bad tag
...@@ -2471,7 +2770,7 @@ test "std.zon enum literals" {...@@ -2471,7 +2770,7 @@ test "std.zon enum literals" {
2471 defer diag.deinit(gpa);2770 defer diag.deinit(gpa);
2472 try std.testing.expectError(2771 try std.testing.expectError(
2473 error.ParseZon,2772 error.ParseZon,
2474 fromSlice(Enum, gpa, ".qux", &diag, .{}),2773 fromSlice(Enum, .{ .gpa = gpa, .source = ".qux", .diag = &diag }),
2475 );2774 );
2476 try std.testing.expectFmt(2775 try std.testing.expectFmt(
2477 \\1:2: error: unexpected enum literal 'qux'2776 \\1:2: error: unexpected enum literal 'qux'
...@@ -2489,7 +2788,7 @@ test "std.zon enum literals" {...@@ -2489,7 +2788,7 @@ test "std.zon enum literals" {
2489 defer diag.deinit(gpa);2788 defer diag.deinit(gpa);
2490 try std.testing.expectError(2789 try std.testing.expectError(
2491 error.ParseZon,2790 error.ParseZon,
2492 fromSlice(Enum, gpa, ".@\"foobarbaz\"", &diag, .{}),2791 fromSlice(Enum, .{ .gpa = gpa, .source = ".@\"foobarbaz\"", .diag = &diag }),
2493 );2792 );
2494 try std.testing.expectFmt(2793 try std.testing.expectFmt(
2495 \\1:2: error: unexpected enum literal 'foobarbaz'2794 \\1:2: error: unexpected enum literal 'foobarbaz'
...@@ -2507,7 +2806,7 @@ test "std.zon enum literals" {...@@ -2507,7 +2806,7 @@ test "std.zon enum literals" {
2507 defer diag.deinit(gpa);2806 defer diag.deinit(gpa);
2508 try std.testing.expectError(2807 try std.testing.expectError(
2509 error.ParseZon,2808 error.ParseZon,
2510 fromSlice(Enum, gpa, "true", &diag, .{}),2809 fromSlice(Enum, .{ .gpa = gpa, .source = "true", .diag = &diag }),
2511 );2810 );
2512 try std.testing.expectFmt("1:1: error: expected enum literal\n", "{f}", .{diag});2811 try std.testing.expectFmt("1:1: error: expected enum literal\n", "{f}", .{diag});
2513 }2812 }
...@@ -2518,7 +2817,7 @@ test "std.zon enum literals" {...@@ -2518,7 +2817,7 @@ test "std.zon enum literals" {
2518 defer diag.deinit(gpa);2817 defer diag.deinit(gpa);
2519 try std.testing.expectError(2818 try std.testing.expectError(
2520 error.ParseZon,2819 error.ParseZon,
2521 fromSlice(Enum, gpa, ".@\"\\x00\"", &diag, .{}),2820 fromSlice(Enum, .{ .gpa = gpa, .source = ".@\"\\x00\"", .diag = &diag }),
2522 );2821 );
2523 try std.testing.expectFmt(2822 try std.testing.expectFmt(
2524 "1:2: error: identifier cannot contain null bytes\n",2823 "1:2: error: identifier cannot contain null bytes\n",
...@@ -2532,8 +2831,16 @@ test "std.zon parse bool" {...@@ -2532,8 +2831,16 @@ test "std.zon parse bool" {
2532 const gpa = std.testing.allocator;2831 const gpa = std.testing.allocator;
25332832
2534 // Correct bools2833 // Correct bools
2535 try std.testing.expectEqual(true, try fromSlice(bool, gpa, "true", null, .{}));2834 try std.testing.expectEqual(true, try fromSlice(bool, .{
2536 try std.testing.expectEqual(false, try fromSlice(bool, gpa, "false", null, .{}));2835 .gpa = gpa,
2836 .source = "true",
2837 .diag = null,
2838 }));
2839 try std.testing.expectEqual(false, try fromSlice(bool, .{
2840 .gpa = gpa,
2841 .source = "false",
2842 .diag = null,
2843 }));
25372844
2538 // Errors2845 // Errors
2539 {2846 {
...@@ -2541,7 +2848,7 @@ test "std.zon parse bool" {...@@ -2541,7 +2848,7 @@ test "std.zon parse bool" {
2541 defer diag.deinit(gpa);2848 defer diag.deinit(gpa);
2542 try std.testing.expectError(2849 try std.testing.expectError(
2543 error.ParseZon,2850 error.ParseZon,
2544 fromSlice(bool, gpa, " foo", &diag, .{}),2851 fromSlice(bool, .{ .gpa = gpa, .source = " foo", .diag = &diag }),
2545 );2852 );
2546 try std.testing.expectFmt(2853 try std.testing.expectFmt(
2547 \\1:2: error: invalid expression2854 \\1:2: error: invalid expression
...@@ -2553,7 +2860,11 @@ test "std.zon parse bool" {...@@ -2553,7 +2860,11 @@ test "std.zon parse bool" {
2553 {2860 {
2554 var diag: Diagnostics = .{};2861 var diag: Diagnostics = .{};
2555 defer diag.deinit(gpa);2862 defer diag.deinit(gpa);
2556 try std.testing.expectError(error.ParseZon, fromSlice(bool, gpa, "123", &diag, .{}));2863 try std.testing.expectError(error.ParseZon, fromSlice(bool, .{
2864 .gpa = gpa,
2865 .source = "123",
2866 .diag = &diag,
2867 }));
2557 try std.testing.expectFmt("1:1: error: expected type 'bool'\n", "{f}", .{diag});2868 try std.testing.expectFmt("1:1: error: expected type 'bool'\n", "{f}", .{diag});
2558 }2869 }
2559}2870}
...@@ -2584,52 +2895,102 @@ test "std.zon parse int" {...@@ -2584,52 +2895,102 @@ test "std.zon parse int" {
2584 const gpa = std.testing.allocator;2895 const gpa = std.testing.allocator;
25852896
2586 // Test various numbers and types2897 // Test various numbers and types
2587 try std.testing.expectEqual(@as(u8, 10), try fromSlice(u8, gpa, "10", null, .{}));2898 try std.testing.expectEqual(@as(u8, 10), try fromSlice(u8, .{
2588 try std.testing.expectEqual(@as(i16, 24), try fromSlice(i16, gpa, "24", null, .{}));2899 .gpa = gpa,
2589 try std.testing.expectEqual(@as(i14, -4), try fromSlice(i14, gpa, "-4", null, .{}));2900 .source = "10",
2590 try std.testing.expectEqual(@as(i32, -123), try fromSlice(i32, gpa, "-123", null, .{}));2901 .diag = null,
2902 }));
2903 try std.testing.expectEqual(@as(i16, 24), try fromSlice(i16, .{
2904 .gpa = gpa,
2905 .source = "24",
2906 .diag = null,
2907 }));
2908 try std.testing.expectEqual(@as(i14, -4), try fromSlice(i14, .{
2909 .gpa = gpa,
2910 .source = "-4",
2911 .diag = null,
2912 }));
2913 try std.testing.expectEqual(@as(i32, -123), try fromSlice(i32, .{
2914 .gpa = gpa,
2915 .source = "-123",
2916 .diag = null,
2917 }));
25912918
2592 // Test limits2919 // Test limits
2593 try std.testing.expectEqual(@as(i8, 127), try fromSlice(i8, gpa, "127", null, .{}));2920 try std.testing.expectEqual(@as(i8, 127), try fromSlice(i8, .{
2594 try std.testing.expectEqual(@as(i8, -128), try fromSlice(i8, gpa, "-128", null, .{}));2921 .gpa = gpa,
2922 .source = "127",
2923 .diag = null,
2924 }));
2925 try std.testing.expectEqual(@as(i8, -128), try fromSlice(i8, .{
2926 .gpa = gpa,
2927 .source = "-128",
2928 .diag = null,
2929 }));
25952930
2596 // Test characters2931 // Test characters
2597 try std.testing.expectEqual(@as(u8, 'a'), try fromSlice(u8, gpa, "'a'", null, .{}));2932 try std.testing.expectEqual(@as(u8, 'a'), try fromSlice(u8, .{
2598 try std.testing.expectEqual(@as(u8, 'z'), try fromSlice(u8, gpa, "'z'", null, .{}));2933 .gpa = gpa,
2934 .source = "'a'",
2935 .diag = null,
2936 }));
2937 try std.testing.expectEqual(@as(u8, 'z'), try fromSlice(u8, .{
2938 .gpa = gpa,
2939 .source = "'z'",
2940 .diag = null,
2941 }));
25992942
2600 // Test big integers2943 // Test big integers
2601 try std.testing.expectEqual(2944 try std.testing.expectEqual(
2602 @as(u65, 36893488147419103231),2945 @as(u65, 36893488147419103231),
2603 try fromSlice(u65, gpa, "36893488147419103231", null, .{}),2946 try fromSlice(u65, .{
2947 .gpa = gpa,
2948 .source = "36893488147419103231",
2949 .diag = null,
2950 }),
2604 );2951 );
2605 try std.testing.expectEqual(2952 try std.testing.expectEqual(
2606 @as(u65, 36893488147419103231),2953 @as(u65, 36893488147419103231),
2607 try fromSlice(u65, gpa, "368934_881_474191032_31", null, .{}),2954 try fromSlice(u65, .{
2955 .gpa = gpa,
2956 .source = "368934_881_474191032_31",
2957 .diag = null,
2958 }),
2608 );2959 );
2609 try std.testing.expectEqual(2960 try std.testing.expectEqual(
2610 @as(u128, 340282366920938463463374607431768211455),2961 @as(u128, 340282366920938463463374607431768211455),
2611 try fromSlice(u128, gpa, "340282366920938463463374607431768211455", null, .{}),2962 try fromSlice(u128, .{
2963 .gpa = gpa,
2964 .source = "340282366920938463463374607431768211455",
2965 .diag = null,
2966 }),
2612 );2967 );
26132968
2614 // Test big integer limits2969 // Test big integer limits
2615 try std.testing.expectEqual(2970 try std.testing.expectEqual(
2616 @as(i66, 36893488147419103231),2971 @as(i66, 36893488147419103231),
2617 try fromSlice(i66, gpa, "36893488147419103231", null, .{}),2972 try fromSlice(i66, .{
2973 .gpa = gpa,
2974 .source = "36893488147419103231",
2975 .diag = null,
2976 }),
2618 );2977 );
2619 try std.testing.expectEqual(2978 try std.testing.expectEqual(
2620 @as(i66, -36893488147419103232),2979 @as(i66, -36893488147419103232),
2621 try fromSlice(i66, gpa, "-36893488147419103232", null, .{}),2980 try fromSlice(i66, .{
2981 .gpa = gpa,
2982 .source = "-36893488147419103232",
2983 .diag = null,
2984 }),
2622 );2985 );
2623 {2986 {
2624 var diag: Diagnostics = .{};2987 var diag: Diagnostics = .{};
2625 defer diag.deinit(gpa);2988 defer diag.deinit(gpa);
2626 try std.testing.expectError(error.ParseZon, fromSlice(2989 try std.testing.expectError(error.ParseZon, fromSlice(i66, .{
2627 i66,2990 .gpa = gpa,
2628 gpa,2991 .source = "36893488147419103232",
2629 "36893488147419103232",2992 .diag = &diag,
2630 &diag,2993 }));
2631 .{},
2632 ));
2633 try std.testing.expectFmt(2994 try std.testing.expectFmt(
2634 "1:1: error: type 'i66' cannot represent value\n",2995 "1:1: error: type 'i66' cannot represent value\n",
2635 "{f}",2996 "{f}",
...@@ -2639,13 +3000,11 @@ test "std.zon parse int" {...@@ -2639,13 +3000,11 @@ test "std.zon parse int" {
2639 {3000 {
2640 var diag: Diagnostics = .{};3001 var diag: Diagnostics = .{};
2641 defer diag.deinit(gpa);3002 defer diag.deinit(gpa);
2642 try std.testing.expectError(error.ParseZon, fromSlice(3003 try std.testing.expectError(error.ParseZon, fromSlice(i66, .{
2643 i66,3004 .gpa = gpa,
2644 gpa,3005 .source = "-36893488147419103233",
2645 "-36893488147419103233",3006 .diag = &diag,
2646 &diag,3007 }));
2647 .{},
2648 ));
2649 try std.testing.expectFmt(3008 try std.testing.expectFmt(
2650 "1:1: error: type 'i66' cannot represent value\n",3009 "1:1: error: type 'i66' cannot represent value\n",
2651 "{f}",3010 "{f}",
...@@ -2654,87 +3013,105 @@ test "std.zon parse int" {...@@ -2654,87 +3013,105 @@ test "std.zon parse int" {
2654 }3013 }
26553014
2656 // Test parsing whole number floats as integers3015 // Test parsing whole number floats as integers
2657 try std.testing.expectEqual(@as(i8, -1), try fromSlice(i8, gpa, "-1.0", null, .{}));3016 try std.testing.expectEqual(@as(i8, -1), try fromSlice(i8, .{
2658 try std.testing.expectEqual(@as(i8, 123), try fromSlice(i8, gpa, "123.0", null, .{}));3017 .gpa = gpa,
3018 .source = "-1.0",
3019 .diag = null,
3020 }));
3021 try std.testing.expectEqual(@as(i8, 123), try fromSlice(i8, .{
3022 .gpa = gpa,
3023 .source = "123.0",
3024 .diag = null,
3025 }));
26593026
2660 // Test non-decimal integers3027 // Test non-decimal integers
2661 try std.testing.expectEqual(@as(i16, 0xff), try fromSlice(i16, gpa, "0xff", null, .{}));3028 try std.testing.expectEqual(@as(i16, 0xff), try fromSlice(i16, .{
2662 try std.testing.expectEqual(@as(i16, -0xff), try fromSlice(i16, gpa, "-0xff", null, .{}));3029 .gpa = gpa,
2663 try std.testing.expectEqual(@as(i16, 0o77), try fromSlice(i16, gpa, "0o77", null, .{}));3030 .source = "0xff",
2664 try std.testing.expectEqual(@as(i16, -0o77), try fromSlice(i16, gpa, "-0o77", null, .{}));3031 .diag = null,
2665 try std.testing.expectEqual(@as(i16, 0b11), try fromSlice(i16, gpa, "0b11", null, .{}));3032 }));
2666 try std.testing.expectEqual(@as(i16, -0b11), try fromSlice(i16, gpa, "-0b11", null, .{}));3033 try std.testing.expectEqual(@as(i16, -0xff), try fromSlice(i16, .{
3034 .gpa = gpa,
3035 .source = "-0xff",
3036 .diag = null,
3037 }));
3038 try std.testing.expectEqual(@as(i16, 0o77), try fromSlice(i16, .{
3039 .gpa = gpa,
3040 .source = "0o77",
3041 .diag = null,
3042 }));
3043 try std.testing.expectEqual(@as(i16, -0o77), try fromSlice(i16, .{
3044 .gpa = gpa,
3045 .source = "-0o77",
3046 .diag = null,
3047 }));
3048 try std.testing.expectEqual(@as(i16, 0b11), try fromSlice(i16, .{
3049 .gpa = gpa,
3050 .source = "0b11",
3051 .diag = null,
3052 }));
3053 try std.testing.expectEqual(@as(i16, -0b11), try fromSlice(i16, .{
3054 .gpa = gpa,
3055 .source = "-0b11",
3056 .diag = null,
3057 }));
26673058
2668 // Test non-decimal big integers3059 // Test non-decimal big integers
2669 try std.testing.expectEqual(@as(u65, 0x1ffffffffffffffff), try fromSlice(3060 try std.testing.expectEqual(@as(u65, 0x1ffffffffffffffff), try fromSlice(u65, .{
2670 u65,3061 .gpa = gpa,
2671 gpa,3062 .source = "0x1ffffffffffffffff",
2672 "0x1ffffffffffffffff",3063 .diag = null,
2673 null,3064 }));
2674 .{},3065 try std.testing.expectEqual(@as(i66, 0x1ffffffffffffffff), try fromSlice(i66, .{
2675 ));3066 .gpa = gpa,
2676 try std.testing.expectEqual(@as(i66, 0x1ffffffffffffffff), try fromSlice(3067 .source = "0x1ffffffffffffffff",
2677 i66,3068 .diag = null,
2678 gpa,3069 }));
2679 "0x1ffffffffffffffff",3070 try std.testing.expectEqual(@as(i66, -0x1ffffffffffffffff), try fromSlice(i66, .{
2680 null,3071 .gpa = gpa,
2681 .{},3072 .source = "-0x1ffffffffffffffff",
2682 ));3073 .diag = null,
2683 try std.testing.expectEqual(@as(i66, -0x1ffffffffffffffff), try fromSlice(3074 }));
2684 i66,3075 try std.testing.expectEqual(@as(u65, 0x1ffffffffffffffff), try fromSlice(u65, .{
2685 gpa,3076 .gpa = gpa,
2686 "-0x1ffffffffffffffff",3077 .source = "0o3777777777777777777777",
2687 null,3078 .diag = null,
2688 .{},3079 }));
2689 ));3080 try std.testing.expectEqual(@as(i66, 0x1ffffffffffffffff), try fromSlice(i66, .{
2690 try std.testing.expectEqual(@as(u65, 0x1ffffffffffffffff), try fromSlice(3081 .gpa = gpa,
2691 u65,3082 .source = "0o3777777777777777777777",
2692 gpa,3083 .diag = null,
2693 "0o3777777777777777777777",3084 }));
2694 null,3085 try std.testing.expectEqual(@as(i66, -0x1ffffffffffffffff), try fromSlice(i66, .{
2695 .{},3086 .gpa = gpa,
2696 ));3087 .source = "-0o3777777777777777777777",
2697 try std.testing.expectEqual(@as(i66, 0x1ffffffffffffffff), try fromSlice(3088 .diag = null,
2698 i66,3089 }));
2699 gpa,3090 try std.testing.expectEqual(@as(u65, 0x1ffffffffffffffff), try fromSlice(u65, .{
2700 "0o3777777777777777777777",3091 .gpa = gpa,
2701 null,3092 .source = "0b11111111111111111111111111111111111111111111111111111111111111111",
2702 .{},3093 .diag = null,
2703 ));3094 }));
2704 try std.testing.expectEqual(@as(i66, -0x1ffffffffffffffff), try fromSlice(3095 try std.testing.expectEqual(@as(i66, 0x1ffffffffffffffff), try fromSlice(i66, .{
2705 i66,3096 .gpa = gpa,
2706 gpa,3097 .source = "0b11111111111111111111111111111111111111111111111111111111111111111",
2707 "-0o3777777777777777777777",3098 .diag = null,
2708 null,3099 }));
2709 .{},3100 try std.testing.expectEqual(@as(i66, -0x1ffffffffffffffff), try fromSlice(i66, .{
2710 ));3101 .gpa = gpa,
2711 try std.testing.expectEqual(@as(u65, 0x1ffffffffffffffff), try fromSlice(3102 .source = "-0b11111111111111111111111111111111111111111111111111111111111111111",
2712 u65,3103 .diag = null,
2713 gpa,3104 }));
2714 "0b11111111111111111111111111111111111111111111111111111111111111111",
2715 null,
2716 .{},
2717 ));
2718 try std.testing.expectEqual(@as(i66, 0x1ffffffffffffffff), try fromSlice(
2719 i66,
2720 gpa,
2721 "0b11111111111111111111111111111111111111111111111111111111111111111",
2722 null,
2723 .{},
2724 ));
2725 try std.testing.expectEqual(@as(i66, -0x1ffffffffffffffff), try fromSlice(
2726 i66,
2727 gpa,
2728 "-0b11111111111111111111111111111111111111111111111111111111111111111",
2729 null,
2730 .{},
2731 ));
27323105
2733 // Number with invalid character in the middle3106 // Number with invalid character in the middle
2734 {3107 {
2735 var diag: Diagnostics = .{};3108 var diag: Diagnostics = .{};
2736 defer diag.deinit(gpa);3109 defer diag.deinit(gpa);
2737 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "32a32", &diag, .{}));3110 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
3111 .gpa = gpa,
3112 .source = "32a32",
3113 .diag = &diag,
3114 }));
2738 try std.testing.expectFmt(3115 try std.testing.expectFmt(
2739 "1:3: error: invalid digit 'a' for decimal base\n",3116 "1:3: error: invalid digit 'a' for decimal base\n",
2740 "{f}",3117 "{f}",
...@@ -2746,7 +3123,11 @@ test "std.zon parse int" {...@@ -2746,7 +3123,11 @@ test "std.zon parse int" {
2746 {3123 {
2747 var diag: Diagnostics = .{};3124 var diag: Diagnostics = .{};
2748 defer diag.deinit(gpa);3125 defer diag.deinit(gpa);
2749 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "true", &diag, .{}));3126 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
3127 .gpa = gpa,
3128 .source = "true",
3129 .diag = &diag,
3130 }));
2750 try std.testing.expectFmt("1:1: error: expected type 'u8'\n", "{f}", .{diag});3131 try std.testing.expectFmt("1:1: error: expected type 'u8'\n", "{f}", .{diag});
2751 }3132 }
27523133
...@@ -2754,7 +3135,11 @@ test "std.zon parse int" {...@@ -2754,7 +3135,11 @@ test "std.zon parse int" {
2754 {3135 {
2755 var diag: Diagnostics = .{};3136 var diag: Diagnostics = .{};
2756 defer diag.deinit(gpa);3137 defer diag.deinit(gpa);
2757 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "256", &diag, .{}));3138 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
3139 .gpa = gpa,
3140 .source = "256",
3141 .diag = &diag,
3142 }));
2758 try std.testing.expectFmt(3143 try std.testing.expectFmt(
2759 "1:1: error: type 'u8' cannot represent value\n",3144 "1:1: error: type 'u8' cannot represent value\n",
2760 "{f}",3145 "{f}",
...@@ -2766,7 +3151,11 @@ test "std.zon parse int" {...@@ -2766,7 +3151,11 @@ test "std.zon parse int" {
2766 {3151 {
2767 var diag: Diagnostics = .{};3152 var diag: Diagnostics = .{};
2768 defer diag.deinit(gpa);3153 defer diag.deinit(gpa);
2769 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-129", &diag, .{}));3154 try std.testing.expectError(error.ParseZon, fromSlice(i8, .{
3155 .gpa = gpa,
3156 .source = "-129",
3157 .diag = &diag,
3158 }));
2770 try std.testing.expectFmt(3159 try std.testing.expectFmt(
2771 "1:1: error: type 'i8' cannot represent value\n",3160 "1:1: error: type 'i8' cannot represent value\n",
2772 "{f}",3161 "{f}",
...@@ -2778,7 +3167,11 @@ test "std.zon parse int" {...@@ -2778,7 +3167,11 @@ test "std.zon parse int" {
2778 {3167 {
2779 var diag: Diagnostics = .{};3168 var diag: Diagnostics = .{};
2780 defer diag.deinit(gpa);3169 defer diag.deinit(gpa);
2781 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "-1", &diag, .{}));3170 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
3171 .gpa = gpa,
3172 .source = "-1",
3173 .diag = &diag,
3174 }));
2782 try std.testing.expectFmt(3175 try std.testing.expectFmt(
2783 "1:1: error: type 'u8' cannot represent value\n",3176 "1:1: error: type 'u8' cannot represent value\n",
2784 "{f}",3177 "{f}",
...@@ -2790,7 +3183,11 @@ test "std.zon parse int" {...@@ -2790,7 +3183,11 @@ test "std.zon parse int" {
2790 {3183 {
2791 var diag: Diagnostics = .{};3184 var diag: Diagnostics = .{};
2792 defer diag.deinit(gpa);3185 defer diag.deinit(gpa);
2793 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "1.5", &diag, .{}));3186 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
3187 .gpa = gpa,
3188 .source = "1.5",
3189 .diag = &diag,
3190 }));
2794 try std.testing.expectFmt(3191 try std.testing.expectFmt(
2795 "1:1: error: type 'u8' cannot represent value\n",3192 "1:1: error: type 'u8' cannot represent value\n",
2796 "{f}",3193 "{f}",
...@@ -2802,7 +3199,11 @@ test "std.zon parse int" {...@@ -2802,7 +3199,11 @@ test "std.zon parse int" {
2802 {3199 {
2803 var diag: Diagnostics = .{};3200 var diag: Diagnostics = .{};
2804 defer diag.deinit(gpa);3201 defer diag.deinit(gpa);
2805 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "-1.0", &diag, .{}));3202 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
3203 .gpa = gpa,
3204 .source = "-1.0",
3205 .diag = &diag,
3206 }));
2806 try std.testing.expectFmt(3207 try std.testing.expectFmt(
2807 "1:1: error: type 'u8' cannot represent value\n",3208 "1:1: error: type 'u8' cannot represent value\n",
2808 "{f}",3209 "{f}",
...@@ -2814,7 +3215,11 @@ test "std.zon parse int" {...@@ -2814,7 +3215,11 @@ test "std.zon parse int" {
2814 {3215 {
2815 var diag: Diagnostics = .{};3216 var diag: Diagnostics = .{};
2816 defer diag.deinit(gpa);3217 defer diag.deinit(gpa);
2817 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-0", &diag, .{}));3218 try std.testing.expectError(error.ParseZon, fromSlice(i8, .{
3219 .gpa = gpa,
3220 .source = "-0",
3221 .diag = &diag,
3222 }));
2818 try std.testing.expectFmt(3223 try std.testing.expectFmt(
2819 \\1:2: error: integer literal '-0' is ambiguous3224 \\1:2: error: integer literal '-0' is ambiguous
2820 \\1:2: note: use '0' for an integer zero3225 \\1:2: note: use '0' for an integer zero
...@@ -2827,7 +3232,11 @@ test "std.zon parse int" {...@@ -2827,7 +3232,11 @@ test "std.zon parse int" {
2827 {3232 {
2828 var diag: Diagnostics = .{};3233 var diag: Diagnostics = .{};
2829 defer diag.deinit(gpa);3234 defer diag.deinit(gpa);
2830 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-0", &diag, .{}));3235 try std.testing.expectError(error.ParseZon, fromSlice(f32, .{
3236 .gpa = gpa,
3237 .source = "-0",
3238 .diag = &diag,
3239 }));
2831 try std.testing.expectFmt(3240 try std.testing.expectFmt(
2832 \\1:2: error: integer literal '-0' is ambiguous3241 \\1:2: error: integer literal '-0' is ambiguous
2833 \\1:2: note: use '0' for an integer zero3242 \\1:2: note: use '0' for an integer zero
...@@ -2838,15 +3247,27 @@ test "std.zon parse int" {...@@ -2838,15 +3247,27 @@ test "std.zon parse int" {
28383247
2839 // Negative float 0 is allowed3248 // Negative float 0 is allowed
2840 try std.testing.expect(3249 try std.testing.expect(
2841 std.math.isNegativeZero(try fromSlice(f32, gpa, "-0.0", null, .{})),3250 std.math.isNegativeZero(try fromSlice(f32, .{
3251 .gpa = gpa,
3252 .source = "-0.0",
3253 .diag = null,
3254 })),
2842 );3255 );
2843 try std.testing.expect(std.math.isPositiveZero(try fromSlice(f32, gpa, "0.0", null, .{})));3256 try std.testing.expect(std.math.isPositiveZero(try fromSlice(f32, .{
3257 .gpa = gpa,
3258 .source = "0.0",
3259 .diag = null,
3260 })));
28443261
2845 // Double negation is not allowed3262 // Double negation is not allowed
2846 {3263 {
2847 var diag: Diagnostics = .{};3264 var diag: Diagnostics = .{};
2848 defer diag.deinit(gpa);3265 defer diag.deinit(gpa);
2849 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "--2", &diag, .{}));3266 try std.testing.expectError(error.ParseZon, fromSlice(i8, .{
3267 .gpa = gpa,
3268 .source = "--2",
3269 .diag = &diag,
3270 }));
2850 try std.testing.expectFmt(3271 try std.testing.expectFmt(
2851 "1:1: error: expected number or 'inf' after '-'\n",3272 "1:1: error: expected number or 'inf' after '-'\n",
2852 "{f}",3273 "{f}",
...@@ -2859,7 +3280,7 @@ test "std.zon parse int" {...@@ -2859,7 +3280,7 @@ test "std.zon parse int" {
2859 defer diag.deinit(gpa);3280 defer diag.deinit(gpa);
2860 try std.testing.expectError(3281 try std.testing.expectError(
2861 error.ParseZon,3282 error.ParseZon,
2862 fromSlice(f32, gpa, "--2.0", &diag, .{}),3283 fromSlice(f32, .{ .gpa = gpa, .source = "--2.0", .diag = &diag }),
2863 );3284 );
2864 try std.testing.expectFmt(3285 try std.testing.expectFmt(
2865 "1:1: error: expected number or 'inf' after '-'\n",3286 "1:1: error: expected number or 'inf' after '-'\n",
...@@ -2872,7 +3293,11 @@ test "std.zon parse int" {...@@ -2872,7 +3293,11 @@ test "std.zon parse int" {
2872 {3293 {
2873 var diag: Diagnostics = .{};3294 var diag: Diagnostics = .{};
2874 defer diag.deinit(gpa);3295 defer diag.deinit(gpa);
2875 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "0xg", &diag, .{}));3296 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
3297 .gpa = gpa,
3298 .source = "0xg",
3299 .diag = &diag,
3300 }));
2876 try std.testing.expectFmt("1:3: error: invalid digit 'g' for hex base\n", "{f}", .{diag});3301 try std.testing.expectFmt("1:3: error: invalid digit 'g' for hex base\n", "{f}", .{diag});
2877 }3302 }
28783303
...@@ -2880,7 +3305,11 @@ test "std.zon parse int" {...@@ -2880,7 +3305,11 @@ test "std.zon parse int" {
2880 {3305 {
2881 var diag: Diagnostics = .{};3306 var diag: Diagnostics = .{};
2882 defer diag.deinit(gpa);3307 defer diag.deinit(gpa);
2883 try std.testing.expectError(error.ParseZon, fromSlice(u8, gpa, "0123", &diag, .{}));3308 try std.testing.expectError(error.ParseZon, fromSlice(u8, .{
3309 .gpa = gpa,
3310 .source = "0123",
3311 .diag = &diag,
3312 }));
2884 try std.testing.expectFmt(3313 try std.testing.expectFmt(
2885 \\1:1: error: number '0123' has leading zero3314 \\1:1: error: number '0123' has leading zero
2886 \\1:1: note: use '0o' prefix for octal literals3315 \\1:1: note: use '0o' prefix for octal literals
...@@ -2895,7 +3324,11 @@ test "std.zon negative char" {...@@ -2895,7 +3324,11 @@ test "std.zon negative char" {
2895 {3324 {
2896 var diag: Diagnostics = .{};3325 var diag: Diagnostics = .{};
2897 defer diag.deinit(gpa);3326 defer diag.deinit(gpa);
2898 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-'a'", &diag, .{}));3327 try std.testing.expectError(error.ParseZon, fromSlice(f32, .{
3328 .gpa = gpa,
3329 .source = "-'a'",
3330 .diag = &diag,
3331 }));
2899 try std.testing.expectFmt(3332 try std.testing.expectFmt(
2900 "1:1: error: expected number or 'inf' after '-'\n",3333 "1:1: error: expected number or 'inf' after '-'\n",
2901 "{f}",3334 "{f}",
...@@ -2905,7 +3338,11 @@ test "std.zon negative char" {...@@ -2905,7 +3338,11 @@ test "std.zon negative char" {
2905 {3338 {
2906 var diag: Diagnostics = .{};3339 var diag: Diagnostics = .{};
2907 defer diag.deinit(gpa);3340 defer diag.deinit(gpa);
2908 try std.testing.expectError(error.ParseZon, fromSlice(i16, gpa, "-'a'", &diag, .{}));3341 try std.testing.expectError(error.ParseZon, fromSlice(i16, .{
3342 .gpa = gpa,
3343 .source = "-'a'",
3344 .diag = &diag,
3345 }));
2909 try std.testing.expectFmt(3346 try std.testing.expectFmt(
2910 "1:1: error: expected number or 'inf' after '-'\n",3347 "1:1: error: expected number or 'inf' after '-'\n",
2911 "{f}",3348 "{f}",
...@@ -2918,81 +3355,149 @@ test "std.zon parse float" {...@@ -2918,81 +3355,149 @@ test "std.zon parse float" {
2918 const gpa = std.testing.allocator;3355 const gpa = std.testing.allocator;
29193356
2920 // Test decimals3357 // Test decimals
2921 try std.testing.expectEqual(@as(f16, 0.5), try fromSlice(f16, gpa, "0.5", null, .{}));3358 try std.testing.expectEqual(@as(f16, 0.5), try fromSlice(f16, .{
3359 .gpa = gpa,
3360 .source = "0.5",
3361 .diag = null,
3362 }));
2922 try std.testing.expectEqual(3363 try std.testing.expectEqual(
2923 @as(f32, 123.456),3364 @as(f32, 123.456),
2924 try fromSlice(f32, gpa, "123.456", null, .{}),3365 try fromSlice(f32, .{ .gpa = gpa, .source = "123.456", .diag = null }),
2925 );3366 );
2926 try std.testing.expectEqual(3367 try std.testing.expectEqual(
2927 @as(f64, -123.456),3368 @as(f64, -123.456),
2928 try fromSlice(f64, gpa, "-123.456", null, .{}),3369 try fromSlice(f64, .{ .gpa = gpa, .source = "-123.456", .diag = null }),
2929 );3370 );
2930 try std.testing.expectEqual(@as(f128, 42.5), try fromSlice(f128, gpa, "42.5", null, .{}));3371 try std.testing.expectEqual(@as(f128, 42.5), try fromSlice(f128, .{
3372 .gpa = gpa,
3373 .source = "42.5",
3374 .diag = null,
3375 }));
29313376
2932 // Test whole numbers with and without decimals3377 // Test whole numbers with and without decimals
2933 try std.testing.expectEqual(@as(f16, 5.0), try fromSlice(f16, gpa, "5.0", null, .{}));3378 try std.testing.expectEqual(@as(f16, 5.0), try fromSlice(f16, .{
2934 try std.testing.expectEqual(@as(f16, 5.0), try fromSlice(f16, gpa, "5", null, .{}));3379 .gpa = gpa,
2935 try std.testing.expectEqual(@as(f32, -102), try fromSlice(f32, gpa, "-102.0", null, .{}));3380 .source = "5.0",
2936 try std.testing.expectEqual(@as(f32, -102), try fromSlice(f32, gpa, "-102", null, .{}));3381 .diag = null,
3382 }));
3383 try std.testing.expectEqual(@as(f16, 5.0), try fromSlice(f16, .{
3384 .gpa = gpa,
3385 .source = "5",
3386 .diag = null,
3387 }));
3388 try std.testing.expectEqual(@as(f32, -102), try fromSlice(f32, .{
3389 .gpa = gpa,
3390 .source = "-102.0",
3391 .diag = null,
3392 }));
3393 try std.testing.expectEqual(@as(f32, -102), try fromSlice(f32, .{
3394 .gpa = gpa,
3395 .source = "-102",
3396 .diag = null,
3397 }));
29373398
2938 // Test characters and negated characters3399 // Test characters and negated characters
2939 try std.testing.expectEqual(@as(f32, 'a'), try fromSlice(f32, gpa, "'a'", null, .{}));3400 try std.testing.expectEqual(@as(f32, 'a'), try fromSlice(f32, .{
2940 try std.testing.expectEqual(@as(f32, 'z'), try fromSlice(f32, gpa, "'z'", null, .{}));3401 .gpa = gpa,
3402 .source = "'a'",
3403 .diag = null,
3404 }));
3405 try std.testing.expectEqual(@as(f32, 'z'), try fromSlice(f32, .{
3406 .gpa = gpa,
3407 .source = "'z'",
3408 .diag = null,
3409 }));
29413410
2942 // Test big integers3411 // Test big integers
2943 try std.testing.expectEqual(3412 try std.testing.expectEqual(
2944 @as(f32, 36893488147419103231.0),3413 @as(f32, 36893488147419103231.0),
2945 try fromSlice(f32, gpa, "36893488147419103231", null, .{}),3414 try fromSlice(f32, .{
3415 .gpa = gpa,
3416 .source = "36893488147419103231",
3417 .diag = null,
3418 }),
2946 );3419 );
2947 try std.testing.expectEqual(3420 try std.testing.expectEqual(
2948 @as(f32, -36893488147419103231.0),3421 @as(f32, -36893488147419103231.0),
2949 try fromSlice(f32, gpa, "-36893488147419103231", null, .{}),3422 try fromSlice(f32, .{
3423 .gpa = gpa,
3424 .source = "-36893488147419103231",
3425 .diag = null,
3426 }),
2950 );3427 );
2951 try std.testing.expectEqual(@as(f128, 0x1ffffffffffffffff), try fromSlice(3428 try std.testing.expectEqual(@as(f128, 0x1ffffffffffffffff), try fromSlice(f128, .{
2952 f128,3429 .gpa = gpa,
2953 gpa,3430 .source = "0x1ffffffffffffffff",
2954 "0x1ffffffffffffffff",3431 .diag = null,
2955 null,3432 }));
2956 .{},3433 try std.testing.expectEqual(@as(f32, @floatFromInt(0x1ffffffffffffffff)), try fromSlice(f32, .{
2957 ));3434 .gpa = gpa,
2958 try std.testing.expectEqual(@as(f32, @floatFromInt(0x1ffffffffffffffff)), try fromSlice(3435 .source = "0x1ffffffffffffffff",
2959 f32,3436 .diag = null,
2960 gpa,3437 }));
2961 "0x1ffffffffffffffff",
2962 null,
2963 .{},
2964 ));
29653438
2966 // Exponents, underscores3439 // Exponents, underscores
2967 try std.testing.expectEqual(3440 try std.testing.expectEqual(
2968 @as(f32, 123.0E+77),3441 @as(f32, 123.0E+77),
2969 try fromSlice(f32, gpa, "12_3.0E+77", null, .{}),3442 try fromSlice(f32, .{
3443 .gpa = gpa,
3444 .source = "12_3.0E+77",
3445 .diag = null,
3446 }),
2970 );3447 );
29713448
2972 // Hexadecimal3449 // Hexadecimal
2973 try std.testing.expectEqual(3450 try std.testing.expectEqual(
2974 @as(f32, 0x103.70p-5),3451 @as(f32, 0x103.70p-5),
2975 try fromSlice(f32, gpa, "0x103.70p-5", null, .{}),3452 try fromSlice(f32, .{
3453 .gpa = gpa,
3454 .source = "0x103.70p-5",
3455 .diag = null,
3456 }),
2976 );3457 );
2977 try std.testing.expectEqual(3458 try std.testing.expectEqual(
2978 @as(f32, -0x103.70),3459 @as(f32, -0x103.70),
2979 try fromSlice(f32, gpa, "-0x103.70", null, .{}),3460 try fromSlice(f32, .{
3461 .gpa = gpa,
3462 .source = "-0x103.70",
3463 .diag = null,
3464 }),
2980 );3465 );
2981 try std.testing.expectEqual(3466 try std.testing.expectEqual(
2982 @as(f32, 0x1234_5678.9ABC_CDEFp-10),3467 @as(f32, 0x1234_5678.9ABC_CDEFp-10),
2983 try fromSlice(f32, gpa, "0x1234_5678.9ABC_CDEFp-10", null, .{}),3468 try fromSlice(f32, .{
3469 .gpa = gpa,
3470 .source = "0x1234_5678.9ABC_CDEFp-10",
3471 .diag = null,
3472 }),
2984 );3473 );
29853474
2986 // inf, nan3475 // inf, nan
2987 try std.testing.expect(std.math.isPositiveInf(try fromSlice(f32, gpa, "inf", null, .{})));3476 try std.testing.expect(std.math.isPositiveInf(try fromSlice(f32, .{
2988 try std.testing.expect(std.math.isNegativeInf(try fromSlice(f32, gpa, "-inf", null, .{})));3477 .gpa = gpa,
2989 try std.testing.expect(std.math.isNan(try fromSlice(f32, gpa, "nan", null, .{})));3478 .source = "inf",
3479 .diag = null,
3480 })));
3481 try std.testing.expect(std.math.isNegativeInf(try fromSlice(f32, .{
3482 .gpa = gpa,
3483 .source = "-inf",
3484 .diag = null,
3485 })));
3486 try std.testing.expect(std.math.isNan(try fromSlice(f32, .{
3487 .gpa = gpa,
3488 .source = "nan",
3489 .diag = null,
3490 })));
29903491
2991 // Negative nan not allowed3492 // Negative nan not allowed
2992 {3493 {
2993 var diag: Diagnostics = .{};3494 var diag: Diagnostics = .{};
2994 defer diag.deinit(gpa);3495 defer diag.deinit(gpa);
2995 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-nan", &diag, .{}));3496 try std.testing.expectError(error.ParseZon, fromSlice(f32, .{
3497 .gpa = gpa,
3498 .source = "-nan",
3499 .diag = &diag,
3500 }));
2996 try std.testing.expectFmt(3501 try std.testing.expectFmt(
2997 "1:1: error: expected number or 'inf' after '-'\n",3502 "1:1: error: expected number or 'inf' after '-'\n",
2998 "{f}",3503 "{f}",
...@@ -3004,7 +3509,11 @@ test "std.zon parse float" {...@@ -3004,7 +3509,11 @@ test "std.zon parse float" {
3004 {3509 {
3005 var diag: Diagnostics = .{};3510 var diag: Diagnostics = .{};
3006 defer diag.deinit(gpa);3511 defer diag.deinit(gpa);
3007 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "nan", &diag, .{}));3512 try std.testing.expectError(error.ParseZon, fromSlice(i8, .{
3513 .gpa = gpa,
3514 .source = "nan",
3515 .diag = &diag,
3516 }));
3008 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{f}", .{diag});3517 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{f}", .{diag});
3009 }3518 }
30103519
...@@ -3012,7 +3521,11 @@ test "std.zon parse float" {...@@ -3012,7 +3521,11 @@ test "std.zon parse float" {
3012 {3521 {
3013 var diag: Diagnostics = .{};3522 var diag: Diagnostics = .{};
3014 defer diag.deinit(gpa);3523 defer diag.deinit(gpa);
3015 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "nan", &diag, .{}));3524 try std.testing.expectError(error.ParseZon, fromSlice(i8, .{
3525 .gpa = gpa,
3526 .source = "nan",
3527 .diag = &diag,
3528 }));
3016 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{f}", .{diag});3529 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{f}", .{diag});
3017 }3530 }
30183531
...@@ -3020,7 +3533,11 @@ test "std.zon parse float" {...@@ -3020,7 +3533,11 @@ test "std.zon parse float" {
3020 {3533 {
3021 var diag: Diagnostics = .{};3534 var diag: Diagnostics = .{};
3022 defer diag.deinit(gpa);3535 defer diag.deinit(gpa);
3023 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "inf", &diag, .{}));3536 try std.testing.expectError(error.ParseZon, fromSlice(i8, .{
3537 .gpa = gpa,
3538 .source = "inf",
3539 .diag = &diag,
3540 }));
3024 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{f}", .{diag});3541 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{f}", .{diag});
3025 }3542 }
30263543
...@@ -3028,7 +3545,11 @@ test "std.zon parse float" {...@@ -3028,7 +3545,11 @@ test "std.zon parse float" {
3028 {3545 {
3029 var diag: Diagnostics = .{};3546 var diag: Diagnostics = .{};
3030 defer diag.deinit(gpa);3547 defer diag.deinit(gpa);
3031 try std.testing.expectError(error.ParseZon, fromSlice(i8, gpa, "-inf", &diag, .{}));3548 try std.testing.expectError(error.ParseZon, fromSlice(i8, .{
3549 .gpa = gpa,
3550 .source = "-inf",
3551 .diag = &diag,
3552 }));
3032 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{f}", .{diag});3553 try std.testing.expectFmt("1:1: error: expected type 'i8'\n", "{f}", .{diag});
3033 }3554 }
30343555
...@@ -3036,7 +3557,11 @@ test "std.zon parse float" {...@@ -3036,7 +3557,11 @@ test "std.zon parse float" {
3036 {3557 {
3037 var diag: Diagnostics = .{};3558 var diag: Diagnostics = .{};
3038 defer diag.deinit(gpa);3559 defer diag.deinit(gpa);
3039 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "foo", &diag, .{}));3560 try std.testing.expectError(error.ParseZon, fromSlice(f32, .{
3561 .gpa = gpa,
3562 .source = "foo",
3563 .diag = &diag,
3564 }));
3040 try std.testing.expectFmt(3565 try std.testing.expectFmt(
3041 \\1:1: error: invalid expression3566 \\1:1: error: invalid expression
3042 \\1:1: note: ZON allows identifiers 'true', 'false', 'null', 'inf', and 'nan'3567 \\1:1: note: ZON allows identifiers 'true', 'false', 'null', 'inf', and 'nan'
...@@ -3048,7 +3573,11 @@ test "std.zon parse float" {...@@ -3048,7 +3573,11 @@ test "std.zon parse float" {
3048 {3573 {
3049 var diag: Diagnostics = .{};3574 var diag: Diagnostics = .{};
3050 defer diag.deinit(gpa);3575 defer diag.deinit(gpa);
3051 try std.testing.expectError(error.ParseZon, fromSlice(f32, gpa, "-foo", &diag, .{}));3576 try std.testing.expectError(error.ParseZon, fromSlice(f32, .{
3577 .gpa = gpa,
3578 .source = "-foo",
3579 .diag = &diag,
3580 }));
3052 try std.testing.expectFmt(3581 try std.testing.expectFmt(
3053 "1:1: error: expected number or 'inf' after '-'\n",3582 "1:1: error: expected number or 'inf' after '-'\n",
3054 "{f}",3583 "{f}",
...@@ -3062,7 +3591,7 @@ test "std.zon parse float" {...@@ -3062,7 +3591,7 @@ test "std.zon parse float" {
3062 defer diag.deinit(gpa);3591 defer diag.deinit(gpa);
3063 try std.testing.expectError(3592 try std.testing.expectError(
3064 error.ParseZon,3593 error.ParseZon,
3065 fromSlice(f32, gpa, "\"foo\"", &diag, .{}),3594 fromSlice(f32, .{ .gpa = gpa, .source = "\"foo\"", .diag = &diag }),
3066 );3595 );
3067 try std.testing.expectFmt("1:1: error: expected type 'f32'\n", "{f}", .{diag});3596 try std.testing.expectFmt("1:1: error: expected type 'f32'\n", "{f}", .{diag});
3068 }3597 }
...@@ -3076,13 +3605,17 @@ test "std.zon free on error" {...@@ -3076,13 +3605,17 @@ test "std.zon free on error" {
3076 y: []const u8,3605 y: []const u8,
3077 z: bool,3606 z: bool,
3078 };3607 };
3079 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Struct, std.testing.allocator,3608 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Struct, .{
3609 .gpa = std.testing.allocator,
3610 .source =
3080 \\.{3611 \\.{
3081 \\ .x = "hello",3612 \\ .x = "hello",
3082 \\ .y = "world",3613 \\ .y = "world",
3083 \\ .z = "fail",3614 \\ .z = "fail",
3084 \\}3615 \\}
3085 , null, .{}));3616 ,
3617 .diag = null,
3618 }));
3086 }3619 }
30873620
3088 // Test freeing partially allocated tuples3621 // Test freeing partially allocated tuples
...@@ -3092,13 +3625,17 @@ test "std.zon free on error" {...@@ -3092,13 +3625,17 @@ test "std.zon free on error" {
3092 []const u8,3625 []const u8,
3093 bool,3626 bool,
3094 };3627 };
3095 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Struct, std.testing.allocator,3628 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Struct, .{
3629 .gpa = std.testing.allocator,
3630 .source =
3096 \\.{3631 \\.{
3097 \\ "hello",3632 \\ "hello",
3098 \\ "world",3633 \\ "world",
3099 \\ "fail",3634 \\ "fail",
3100 \\}3635 \\}
3101 , null, .{}));3636 ,
3637 .diag = null,
3638 }));
3102 }3639 }
31033640
3104 // Test freeing structs with missing fields3641 // Test freeing structs with missing fields
...@@ -3107,62 +3644,66 @@ test "std.zon free on error" {...@@ -3107,62 +3644,66 @@ test "std.zon free on error" {
3107 x: []const u8,3644 x: []const u8,
3108 y: bool,3645 y: bool,
3109 };3646 };
3110 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Struct, std.testing.allocator,3647 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Struct, .{
3648 .gpa = std.testing.allocator,
3649 .source =
3111 \\.{3650 \\.{
3112 \\ .x = "hello",3651 \\ .x = "hello",
3113 \\}3652 \\}
3114 , null, .{}));3653 ,
3654 .diag = null,
3655 }));
3115 }3656 }
31163657
3117 // Test freeing partially allocated arrays3658 // Test freeing partially allocated arrays
3118 {3659 {
3119 try std.testing.expectError(error.ParseZon, fromSliceAlloc(3660 try std.testing.expectError(error.ParseZon, fromSliceAlloc([3][]const u8, .{
3120 [3][]const u8,3661 .gpa = std.testing.allocator,
3121 std.testing.allocator,3662 .source =
3122 \\.{3663 \\.{
3123 \\ "hello",3664 \\ "hello",
3124 \\ false,3665 \\ false,
3125 \\ false,3666 \\ false,
3126 \\}3667 \\}
3127 ,3668 ,
3128 null,3669 .diag = null,
3129 .{},3670 }));
3130 ));
3131 }3671 }
31323672
3133 // Test freeing partially allocated slices3673 // Test freeing partially allocated slices
3134 {3674 {
3135 try std.testing.expectError(error.ParseZon, fromSliceAlloc(3675 try std.testing.expectError(error.ParseZon, fromSliceAlloc([][]const u8, .{
3136 [][]const u8,3676 .gpa = std.testing.allocator,
3137 std.testing.allocator,3677 .source =
3138 \\.{3678 \\.{
3139 \\ "hello",3679 \\ "hello",
3140 \\ "world",3680 \\ "world",
3141 \\ false,3681 \\ false,
3142 \\}3682 \\}
3143 ,3683 ,
3144 null,3684 .diag = null,
3145 .{},3685 }));
3146 ));
3147 }3686 }
31483687
3149 // We can parse types that can't be freed, as long as they contain no allocations, e.g. untagged3688 // We can parse types that can't be freed, as long as they contain no allocations, e.g. untagged
3150 // unions.3689 // unions.
3151 try std.testing.expectEqual(3690 try std.testing.expectEqual(
3152 @as(f32, 1.5),3691 @as(f32, 1.5),
3153 (try fromSlice(union { x: f32 }, std.testing.allocator, ".{ .x = 1.5 }", null, .{})).x,3692 (try fromSlice(union { x: f32 }, .{
3693 .gpa = std.testing.allocator,
3694 .source = ".{ .x = 1.5 }",
3695 .diag = null,
3696 })).x,
3154 );3697 );
31553698
3156 // We can also parse types that can't be freed if it's impossible for an error to occur after3699 // We can also parse types that can't be freed if it's impossible for an error to occur after
3157 // the allocation, as is the case here.3700 // the allocation, as is the case here.
3158 {3701 {
3159 const result = try fromSliceAlloc(3702 const result = try fromSliceAlloc(union { x: []const u8 }, .{
3160 union { x: []const u8 },3703 .gpa = std.testing.allocator,
3161 std.testing.allocator,3704 .source = ".{ .x = \"foo\" }",
3162 ".{ .x = \"foo\" }",3705 .diag = null,
3163 null,3706 });
3164 .{},
3165 );
3166 defer free(std.testing.allocator, result.x);3707 defer free(std.testing.allocator, result.x);
3167 try std.testing.expectEqualStrings("foo", result.x);3708 try std.testing.expectEqualStrings("foo", result.x);
3168 }3709 }
...@@ -3175,13 +3716,12 @@ test "std.zon free on error" {...@@ -3175,13 +3716,12 @@ test "std.zon free on error" {
3175 union { x: []const u8 },3716 union { x: []const u8 },
3176 bool,3717 bool,
3177 };3718 };
3178 const result = try fromSliceAlloc(3719 const result = try fromSliceAlloc(S, .{
3179 S,3720 .gpa = std.testing.allocator,
3180 std.testing.allocator,3721 .source = ".{ .{ .x = \"foo\" }, true }",
3181 ".{ .{ .x = \"foo\" }, true }",3722 .free_on_error = false,
3182 null,3723 .diag = null,
3183 .{ .free_on_error = false },3724 });
3184 );
3185 defer free(std.testing.allocator, result[0].x);3725 defer free(std.testing.allocator, result[0].x);
3186 try std.testing.expectEqualStrings("foo", result[0].x);3726 try std.testing.expectEqualStrings("foo", result[0].x);
3187 try std.testing.expect(result[1]);3727 try std.testing.expect(result[1]);
...@@ -3193,15 +3733,12 @@ test "std.zon free on error" {...@@ -3193,15 +3733,12 @@ test "std.zon free on error" {
3193 a: union { x: []const u8 },3733 a: union { x: []const u8 },
3194 b: bool,3734 b: bool,
3195 };3735 };
3196 const result = try fromSliceAlloc(3736 const result = try fromSliceAlloc(S, .{
3197 S,3737 .gpa = std.testing.allocator,
3198 std.testing.allocator,3738 .source = ".{ .a = .{ .x = \"foo\" }, .b = true }",
3199 ".{ .a = .{ .x = \"foo\" }, .b = true }",3739 .free_on_error = false,
3200 null,3740 .diag = null,
3201 .{3741 });
3202 .free_on_error = false,
3203 },
3204 );
3205 defer free(std.testing.allocator, result.a.x);3742 defer free(std.testing.allocator, result.a.x);
3206 try std.testing.expectEqualStrings("foo", result.a.x);3743 try std.testing.expectEqualStrings("foo", result.a.x);
3207 try std.testing.expect(result.b);3744 try std.testing.expect(result.b);
...@@ -3210,15 +3747,12 @@ test "std.zon free on error" {...@@ -3210,15 +3747,12 @@ test "std.zon free on error" {
3210 // Again but for arrays.3747 // Again but for arrays.
3211 {3748 {
3212 const S = [2]union { x: []const u8 };3749 const S = [2]union { x: []const u8 };
3213 const result = try fromSliceAlloc(3750 const result = try fromSliceAlloc(S, .{
3214 S,3751 .gpa = std.testing.allocator,
3215 std.testing.allocator,3752 .source = ".{ .{ .x = \"foo\" }, .{ .x = \"bar\" } }",
3216 ".{ .{ .x = \"foo\" }, .{ .x = \"bar\" } }",3753 .free_on_error = false,
3217 null,3754 .diag = null,
3218 .{3755 });
3219 .free_on_error = false,
3220 },
3221 );
3222 defer free(std.testing.allocator, result[0].x);3756 defer free(std.testing.allocator, result[0].x);
3223 defer free(std.testing.allocator, result[1].x);3757 defer free(std.testing.allocator, result[1].x);
3224 try std.testing.expectEqualStrings("foo", result[0].x);3758 try std.testing.expectEqualStrings("foo", result[0].x);
...@@ -3228,15 +3762,12 @@ test "std.zon free on error" {...@@ -3228,15 +3762,12 @@ test "std.zon free on error" {
3228 // Again but for slices.3762 // Again but for slices.
3229 {3763 {
3230 const S = []union { x: []const u8 };3764 const S = []union { x: []const u8 };
3231 const result = try fromSliceAlloc(3765 const result = try fromSliceAlloc(S, .{
3232 S,3766 .gpa = std.testing.allocator,
3233 std.testing.allocator,3767 .source = ".{ .{ .x = \"foo\" }, .{ .x = \"bar\" } }",
3234 ".{ .{ .x = \"foo\" }, .{ .x = \"bar\" } }",3768 .free_on_error = false,
3235 null,3769 .diag = null,
3236 .{3770 });
3237 .free_on_error = false,
3238 },
3239 );
3240 defer std.testing.allocator.free(result);3771 defer std.testing.allocator.free(result);
3241 defer free(std.testing.allocator, result[0].x);3772 defer free(std.testing.allocator, result[0].x);
3242 defer free(std.testing.allocator, result[1].x);3773 defer free(std.testing.allocator, result[1].x);
...@@ -3254,37 +3785,53 @@ test "std.zon vector" {...@@ -3254,37 +3785,53 @@ test "std.zon vector" {
3254 // Passing cases3785 // Passing cases
3255 try std.testing.expectEqual(3786 try std.testing.expectEqual(
3256 @Vector(0, bool){},3787 @Vector(0, bool){},
3257 try fromSlice(@Vector(0, bool), gpa, ".{}", null, .{}),3788 try fromSlice(@Vector(0, bool), .{ .gpa = gpa, .source = ".{}", .diag = null }),
3258 );3789 );
3259 try std.testing.expectEqual(3790 try std.testing.expectEqual(
3260 @Vector(3, bool){ true, false, true },3791 @Vector(3, bool){ true, false, true },
3261 try fromSlice(@Vector(3, bool), gpa, ".{true, false, true}", null, .{}),3792 try fromSlice(@Vector(3, bool), .{
3793 .gpa = gpa,
3794 .source = ".{true, false, true}",
3795 .diag = null,
3796 }),
3262 );3797 );
32633798
3264 try std.testing.expectEqual(3799 try std.testing.expectEqual(
3265 @Vector(0, f32){},3800 @Vector(0, f32){},
3266 try fromSlice(@Vector(0, f32), gpa, ".{}", null, .{}),3801 try fromSlice(@Vector(0, f32), .{ .gpa = gpa, .source = ".{}", .diag = null }),
3267 );3802 );
3268 try std.testing.expectEqual(3803 try std.testing.expectEqual(
3269 @Vector(3, f32){ 1.5, 2.5, 3.5 },3804 @Vector(3, f32){ 1.5, 2.5, 3.5 },
3270 try fromSlice(@Vector(3, f32), gpa, ".{1.5, 2.5, 3.5}", null, .{}),3805 try fromSlice(@Vector(3, f32), .{
3806 .gpa = gpa,
3807 .source = ".{1.5, 2.5, 3.5}",
3808 .diag = null,
3809 }),
3271 );3810 );
32723811
3273 try std.testing.expectEqual(3812 try std.testing.expectEqual(
3274 @Vector(0, u8){},3813 @Vector(0, u8){},
3275 try fromSlice(@Vector(0, u8), gpa, ".{}", null, .{}),3814 try fromSlice(@Vector(0, u8), .{ .gpa = gpa, .source = ".{}", .diag = null }),
3276 );3815 );
3277 try std.testing.expectEqual(3816 try std.testing.expectEqual(
3278 @Vector(3, u8){ 2, 4, 6 },3817 @Vector(3, u8){ 2, 4, 6 },
3279 try fromSlice(@Vector(3, u8), gpa, ".{2, 4, 6}", null, .{}),3818 try fromSlice(@Vector(3, u8), .{ .gpa = gpa, .source = ".{2, 4, 6}", .diag = null }),
3280 );3819 );
32813820
3282 {3821 {
3283 try std.testing.expectEqual(3822 try std.testing.expectEqual(
3284 @Vector(0, *const u8){},3823 @Vector(0, *const u8){},
3285 try fromSliceAlloc(@Vector(0, *const u8), gpa, ".{}", null, .{}),3824 try fromSliceAlloc(@Vector(0, *const u8), .{
3825 .gpa = gpa,
3826 .source = ".{}",
3827 .diag = null,
3828 }),
3286 );3829 );
3287 const pointers = try fromSliceAlloc(@Vector(3, *const u8), gpa, ".{2, 4, 6}", null, .{});3830 const pointers = try fromSliceAlloc(@Vector(3, *const u8), .{
3831 .gpa = gpa,
3832 .source = ".{2, 4, 6}",
3833 .diag = null,
3834 });
3288 defer free(gpa, pointers);3835 defer free(gpa, pointers);
3289 try std.testing.expectEqualDeep(@Vector(3, *const u8){ &2, &4, &6 }, pointers);3836 try std.testing.expectEqualDeep(@Vector(3, *const u8){ &2, &4, &6 }, pointers);
3290 }3837 }
...@@ -3292,9 +3839,17 @@ test "std.zon vector" {...@@ -3292,9 +3839,17 @@ test "std.zon vector" {
3292 {3839 {
3293 try std.testing.expectEqual(3840 try std.testing.expectEqual(
3294 @Vector(0, ?*const u8){},3841 @Vector(0, ?*const u8){},
3295 try fromSliceAlloc(@Vector(0, ?*const u8), gpa, ".{}", null, .{}),3842 try fromSliceAlloc(@Vector(0, ?*const u8), .{
3843 .gpa = gpa,
3844 .source = ".{}",
3845 .diag = null,
3846 }),
3296 );3847 );
3297 const pointers = try fromSliceAlloc(@Vector(3, ?*const u8), gpa, ".{2, null, 6}", null, .{});3848 const pointers = try fromSliceAlloc(@Vector(3, ?*const u8), .{
3849 .gpa = gpa,
3850 .source = ".{2, null, 6}",
3851 .diag = null,
3852 });
3298 defer free(gpa, pointers);3853 defer free(gpa, pointers);
3299 try std.testing.expectEqualDeep(@Vector(3, ?*const u8){ &2, null, &6 }, pointers);3854 try std.testing.expectEqualDeep(@Vector(3, ?*const u8){ &2, null, &6 }, pointers);
3300 }3855 }
...@@ -3305,7 +3860,11 @@ test "std.zon vector" {...@@ -3305,7 +3860,11 @@ test "std.zon vector" {
3305 defer diag.deinit(gpa);3860 defer diag.deinit(gpa);
3306 try std.testing.expectError(3861 try std.testing.expectError(
3307 error.ParseZon,3862 error.ParseZon,
3308 fromSlice(@Vector(2, f32), gpa, ".{0.5}", &diag, .{}),3863 fromSlice(@Vector(2, f32), .{
3864 .gpa = gpa,
3865 .source = ".{0.5}",
3866 .diag = &diag,
3867 }),
3309 );3868 );
3310 try std.testing.expectFmt(3869 try std.testing.expectFmt(
3311 "1:2: error: expected 2 array elements; found 1\n",3870 "1:2: error: expected 2 array elements; found 1\n",
...@@ -3320,7 +3879,11 @@ test "std.zon vector" {...@@ -3320,7 +3879,11 @@ test "std.zon vector" {
3320 defer diag.deinit(gpa);3879 defer diag.deinit(gpa);
3321 try std.testing.expectError(3880 try std.testing.expectError(
3322 error.ParseZon,3881 error.ParseZon,
3323 fromSlice(@Vector(2, f32), gpa, ".{0.5, 1.5, 2.5}", &diag, .{}),3882 fromSlice(@Vector(2, f32), .{
3883 .gpa = gpa,
3884 .source = ".{0.5, 1.5, 2.5}",
3885 .diag = &diag,
3886 }),
3324 );3887 );
3325 try std.testing.expectFmt(3888 try std.testing.expectFmt(
3326 "1:13: error: index 2 outside of array of length 2\n",3889 "1:13: error: index 2 outside of array of length 2\n",
...@@ -3335,7 +3898,11 @@ test "std.zon vector" {...@@ -3335,7 +3898,11 @@ test "std.zon vector" {
3335 defer diag.deinit(gpa);3898 defer diag.deinit(gpa);
3336 try std.testing.expectError(3899 try std.testing.expectError(
3337 error.ParseZon,3900 error.ParseZon,
3338 fromSlice(@Vector(3, f32), gpa, ".{0.5, true, 2.5}", &diag, .{}),3901 fromSlice(@Vector(3, f32), .{
3902 .gpa = gpa,
3903 .source = ".{0.5, true, 2.5}",
3904 .diag = &diag,
3905 }),
3339 );3906 );
3340 try std.testing.expectFmt(3907 try std.testing.expectFmt(
3341 "1:8: error: expected type 'f32'\n",3908 "1:8: error: expected type 'f32'\n",
...@@ -3350,7 +3917,7 @@ test "std.zon vector" {...@@ -3350,7 +3917,7 @@ test "std.zon vector" {
3350 defer diag.deinit(gpa);3917 defer diag.deinit(gpa);
3351 try std.testing.expectError(3918 try std.testing.expectError(
3352 error.ParseZon,3919 error.ParseZon,
3353 fromSlice(@Vector(3, u8), gpa, "true", &diag, .{}),3920 fromSlice(@Vector(3, u8), .{ .gpa = gpa, .source = "true", .diag = &diag }),
3354 );3921 );
3355 try std.testing.expectFmt("1:1: error: expected type '@Vector(3, u8)'\n", "{f}", .{diag});3922 try std.testing.expectFmt("1:1: error: expected type '@Vector(3, u8)'\n", "{f}", .{diag});
3356 }3923 }
...@@ -3361,7 +3928,11 @@ test "std.zon vector" {...@@ -3361,7 +3928,11 @@ test "std.zon vector" {
3361 defer diag.deinit(gpa);3928 defer diag.deinit(gpa);
3362 try std.testing.expectError(3929 try std.testing.expectError(
3363 error.ParseZon,3930 error.ParseZon,
3364 fromSliceAlloc(@Vector(3, *u8), gpa, ".{1, true, 3}", &diag, .{}),3931 fromSliceAlloc(@Vector(3, *u8), .{
3932 .gpa = gpa,
3933 .source = ".{1, true, 3}",
3934 .diag = &diag,
3935 }),
3365 );3936 );
3366 try std.testing.expectFmt("1:6: error: expected type 'u8'\n", "{f}", .{diag});3937 try std.testing.expectFmt("1:6: error: expected type 'u8'\n", "{f}", .{diag});
3367 }3938 }
...@@ -3372,77 +3943,133 @@ test "std.zon add pointers" {...@@ -3372,77 +3943,133 @@ test "std.zon add pointers" {
33723943
3373 // Primitive with varying levels of pointers3944 // Primitive with varying levels of pointers
3374 {3945 {
3375 const result = try fromSliceAlloc(*u32, gpa, "10", null, .{});3946 const result = try fromSliceAlloc(*u32, .{
3947 .gpa = gpa,
3948 .source = "10",
3949 .diag = null,
3950 });
3376 defer free(gpa, result);3951 defer free(gpa, result);
3377 try std.testing.expectEqual(@as(u32, 10), result.*);3952 try std.testing.expectEqual(@as(u32, 10), result.*);
3378 }3953 }
33793954
3380 {3955 {
3381 const result = try fromSliceAlloc(**u32, gpa, "10", null, .{});3956 const result = try fromSliceAlloc(**u32, .{
3957 .gpa = gpa,
3958 .source = "10",
3959 .diag = null,
3960 });
3382 defer free(gpa, result);3961 defer free(gpa, result);
3383 try std.testing.expectEqual(@as(u32, 10), result.*.*);3962 try std.testing.expectEqual(@as(u32, 10), result.*.*);
3384 }3963 }
33853964
3386 {3965 {
3387 const result = try fromSliceAlloc(***u32, gpa, "10", null, .{});3966 const result = try fromSliceAlloc(***u32, .{
3967 .gpa = gpa,
3968 .source = "10",
3969 .diag = null,
3970 });
3388 defer free(gpa, result);3971 defer free(gpa, result);
3389 try std.testing.expectEqual(@as(u32, 10), result.*.*.*);3972 try std.testing.expectEqual(@as(u32, 10), result.*.*.*);
3390 }3973 }
33913974
3392 // Primitive optional with varying levels of pointers3975 // Primitive optional with varying levels of pointers
3393 {3976 {
3394 const some = try fromSliceAlloc(?*u32, gpa, "10", null, .{});3977 const some = try fromSliceAlloc(?*u32, .{
3978 .gpa = gpa,
3979 .source = "10",
3980 .diag = null,
3981 });
3395 defer free(gpa, some);3982 defer free(gpa, some);
3396 try std.testing.expectEqual(@as(u32, 10), some.?.*);3983 try std.testing.expectEqual(@as(u32, 10), some.?.*);
33973984
3398 const none = try fromSliceAlloc(?*u32, gpa, "null", null, .{});3985 const none = try fromSliceAlloc(?*u32, .{
3986 .gpa = gpa,
3987 .source = "null",
3988 .diag = null,
3989 });
3399 defer free(gpa, none);3990 defer free(gpa, none);
3400 try std.testing.expectEqual(null, none);3991 try std.testing.expectEqual(null, none);
3401 }3992 }
34023993
3403 {3994 {
3404 const some = try fromSliceAlloc(*?u32, gpa, "10", null, .{});3995 const some = try fromSliceAlloc(*?u32, .{
3996 .gpa = gpa,
3997 .source = "10",
3998 .diag = null,
3999 });
3405 defer free(gpa, some);4000 defer free(gpa, some);
3406 try std.testing.expectEqual(@as(u32, 10), some.*.?);4001 try std.testing.expectEqual(@as(u32, 10), some.*.?);
34074002
3408 const none = try fromSliceAlloc(*?u32, gpa, "null", null, .{});4003 const none = try fromSliceAlloc(*?u32, .{
4004 .gpa = gpa,
4005 .source = "null",
4006 .diag = null,
4007 });
3409 defer free(gpa, none);4008 defer free(gpa, none);
3410 try std.testing.expectEqual(null, none.*);4009 try std.testing.expectEqual(null, none.*);
3411 }4010 }
34124011
3413 {4012 {
3414 const some = try fromSliceAlloc(?**u32, gpa, "10", null, .{});4013 const some = try fromSliceAlloc(?**u32, .{
4014 .gpa = gpa,
4015 .source = "10",
4016 .diag = null,
4017 });
3415 defer free(gpa, some);4018 defer free(gpa, some);
3416 try std.testing.expectEqual(@as(u32, 10), some.?.*.*);4019 try std.testing.expectEqual(@as(u32, 10), some.?.*.*);
34174020
3418 const none = try fromSliceAlloc(?**u32, gpa, "null", null, .{});4021 const none = try fromSliceAlloc(?**u32, .{
4022 .gpa = gpa,
4023 .source = "null",
4024 .diag = null,
4025 });
3419 defer free(gpa, none);4026 defer free(gpa, none);
3420 try std.testing.expectEqual(null, none);4027 try std.testing.expectEqual(null, none);
3421 }4028 }
34224029
3423 {4030 {
3424 const some = try fromSliceAlloc(*?*u32, gpa, "10", null, .{});4031 const some = try fromSliceAlloc(*?*u32, .{
4032 .gpa = gpa,
4033 .source = "10",
4034 .diag = null,
4035 });
3425 defer free(gpa, some);4036 defer free(gpa, some);
3426 try std.testing.expectEqual(@as(u32, 10), some.*.?.*);4037 try std.testing.expectEqual(@as(u32, 10), some.*.?.*);
34274038
3428 const none = try fromSliceAlloc(*?*u32, gpa, "null", null, .{});4039 const none = try fromSliceAlloc(*?*u32, .{
4040 .gpa = gpa,
4041 .source = "null",
4042 .diag = null,
4043 });
3429 defer free(gpa, none);4044 defer free(gpa, none);
3430 try std.testing.expectEqual(null, none.*);4045 try std.testing.expectEqual(null, none.*);
3431 }4046 }
34324047
3433 {4048 {
3434 const some = try fromSliceAlloc(**?u32, gpa, "10", null, .{});4049 const some = try fromSliceAlloc(**?u32, .{
4050 .gpa = gpa,
4051 .source = "10",
4052 .diag = null,
4053 });
3435 defer free(gpa, some);4054 defer free(gpa, some);
3436 try std.testing.expectEqual(@as(u32, 10), some.*.*.?);4055 try std.testing.expectEqual(@as(u32, 10), some.*.*.?);
34374056
3438 const none = try fromSliceAlloc(**?u32, gpa, "null", null, .{});4057 const none = try fromSliceAlloc(**?u32, .{
4058 .gpa = gpa,
4059 .source = "null",
4060 .diag = null,
4061 });
3439 defer free(gpa, none);4062 defer free(gpa, none);
3440 try std.testing.expectEqual(null, none.*.*);4063 try std.testing.expectEqual(null, none.*.*);
3441 }4064 }
34424065
3443 // Pointer to an array4066 // Pointer to an array
3444 {4067 {
3445 const result = try fromSliceAlloc(*[3]u8, gpa, ".{ 1, 2, 3 }", null, .{});4068 const result = try fromSliceAlloc(*[3]u8, .{
4069 .gpa = gpa,
4070 .source = ".{ 1, 2, 3 }",
4071 .diag = null,
4072 });
3446 defer free(gpa, result);4073 defer free(gpa, result);
3447 try std.testing.expectEqual([3]u8{ 1, 2, 3 }, result.*);4074 try std.testing.expectEqual([3]u8{ 1, 2, 3 }, result.*);
3448 }4075 }
...@@ -3465,7 +4092,9 @@ test "std.zon add pointers" {...@@ -3465,7 +4092,9 @@ test "std.zon add pointers" {
3465 .f2 = &null,4092 .f2 = &null,
3466 };4093 };
34674094
3468 const found = try fromSliceAlloc(?*Outer, gpa,4095 const found = try fromSliceAlloc(?*Outer, .{
4096 .gpa = gpa,
4097 .source =
3469 \\.{4098 \\.{
3470 \\ .f1 = .{4099 \\ .f1 = .{
3471 \\ .f1 = null,4100 \\ .f1 = null,
...@@ -3473,7 +4102,9 @@ test "std.zon add pointers" {...@@ -3473,7 +4102,9 @@ test "std.zon add pointers" {
3473 \\ },4102 \\ },
3474 \\ .f2 = null,4103 \\ .f2 = null,
3475 \\}4104 \\}
3476 , null, .{});4105 ,
4106 .diag = null,
4107 });
3477 defer free(gpa, found);4108 defer free(gpa, found);
34784109
3479 try std.testing.expectEqualDeep(expected, found.?.*);4110 try std.testing.expectEqualDeep(expected, found.?.*);
...@@ -3485,7 +4116,7 @@ test "std.zon add pointers" {...@@ -3485,7 +4116,7 @@ test "std.zon add pointers" {
3485 defer diag.deinit(gpa);4116 defer diag.deinit(gpa);
3486 try std.testing.expectError(4117 try std.testing.expectError(
3487 error.ParseZon,4118 error.ParseZon,
3488 fromSliceAlloc(*const ?*const u8, gpa, "true", &diag, .{}),4119 fromSliceAlloc(*const ?*const u8, .{ .gpa = gpa, .source = "true", .diag = &diag }),
3489 );4120 );
3490 try std.testing.expectFmt("1:1: error: expected type '?u8'\n", "{f}", .{diag});4121 try std.testing.expectFmt("1:1: error: expected type '?u8'\n", "{f}", .{diag});
3491 }4122 }
...@@ -3495,7 +4126,7 @@ test "std.zon add pointers" {...@@ -3495,7 +4126,7 @@ test "std.zon add pointers" {
3495 defer diag.deinit(gpa);4126 defer diag.deinit(gpa);
3496 try std.testing.expectError(4127 try std.testing.expectError(
3497 error.ParseZon,4128 error.ParseZon,
3498 fromSliceAlloc(*const ?*const f32, gpa, "true", &diag, .{}),4129 fromSliceAlloc(*const ?*const f32, .{ .gpa = gpa, .source = "true", .diag = &diag }),
3499 );4130 );
3500 try std.testing.expectFmt("1:1: error: expected type '?f32'\n", "{f}", .{diag});4131 try std.testing.expectFmt("1:1: error: expected type '?f32'\n", "{f}", .{diag});
3501 }4132 }
...@@ -3505,7 +4136,11 @@ test "std.zon add pointers" {...@@ -3505,7 +4136,11 @@ test "std.zon add pointers" {
3505 defer diag.deinit(gpa);4136 defer diag.deinit(gpa);
3506 try std.testing.expectError(4137 try std.testing.expectError(
3507 error.ParseZon,4138 error.ParseZon,
3508 fromSliceAlloc(*const ?*const @Vector(3, u8), gpa, "true", &diag, .{}),4139 fromSliceAlloc(*const ?*const @Vector(3, u8), .{
4140 .gpa = gpa,
4141 .source = "true",
4142 .diag = &diag,
4143 }),
3509 );4144 );
3510 try std.testing.expectFmt("1:1: error: expected type '?@Vector(3, u8)'\n", "{f}", .{diag});4145 try std.testing.expectFmt("1:1: error: expected type '?@Vector(3, u8)'\n", "{f}", .{diag});
3511 }4146 }
...@@ -3515,7 +4150,7 @@ test "std.zon add pointers" {...@@ -3515,7 +4150,7 @@ test "std.zon add pointers" {
3515 defer diag.deinit(gpa);4150 defer diag.deinit(gpa);
3516 try std.testing.expectError(4151 try std.testing.expectError(
3517 error.ParseZon,4152 error.ParseZon,
3518 fromSliceAlloc(*const ?*const bool, gpa, "10", &diag, .{}),4153 fromSliceAlloc(*const ?*const bool, .{ .gpa = gpa, .source = "10", .diag = &diag }),
3519 );4154 );
3520 try std.testing.expectFmt("1:1: error: expected type '?bool'\n", "{f}", .{diag});4155 try std.testing.expectFmt("1:1: error: expected type '?bool'\n", "{f}", .{diag});
3521 }4156 }
...@@ -3525,7 +4160,7 @@ test "std.zon add pointers" {...@@ -3525,7 +4160,7 @@ test "std.zon add pointers" {
3525 defer diag.deinit(gpa);4160 defer diag.deinit(gpa);
3526 try std.testing.expectError(4161 try std.testing.expectError(
3527 error.ParseZon,4162 error.ParseZon,
3528 fromSliceAlloc(*const ?*const struct { a: i32 }, gpa, "true", &diag, .{}),4163 fromSliceAlloc(*const ?*const struct { a: i32 }, .{ .gpa = gpa, .source = "true", .diag = &diag }),
3529 );4164 );
3530 try std.testing.expectFmt("1:1: error: expected optional struct\n", "{f}", .{diag});4165 try std.testing.expectFmt("1:1: error: expected optional struct\n", "{f}", .{diag});
3531 }4166 }
...@@ -3535,7 +4170,7 @@ test "std.zon add pointers" {...@@ -3535,7 +4170,7 @@ test "std.zon add pointers" {
3535 defer diag.deinit(gpa);4170 defer diag.deinit(gpa);
3536 try std.testing.expectError(4171 try std.testing.expectError(
3537 error.ParseZon,4172 error.ParseZon,
3538 fromSliceAlloc(*const ?*const struct { i32 }, gpa, "true", &diag, .{}),4173 fromSliceAlloc(*const ?*const struct { i32 }, .{ .gpa = gpa, .source = "true", .diag = &diag }),
3539 );4174 );
3540 try std.testing.expectFmt("1:1: error: expected optional tuple\n", "{f}", .{diag});4175 try std.testing.expectFmt("1:1: error: expected optional tuple\n", "{f}", .{diag});
3541 }4176 }
...@@ -3545,7 +4180,7 @@ test "std.zon add pointers" {...@@ -3545,7 +4180,7 @@ test "std.zon add pointers" {
3545 defer diag.deinit(gpa);4180 defer diag.deinit(gpa);
3546 try std.testing.expectError(4181 try std.testing.expectError(
3547 error.ParseZon,4182 error.ParseZon,
3548 fromSliceAlloc(*const ?*const union { x: void }, gpa, "true", &diag, .{}),4183 fromSliceAlloc(*const ?*const union { x: void }, .{ .gpa = gpa, .source = "true", .diag = &diag }),
3549 );4184 );
3550 try std.testing.expectFmt("1:1: error: expected optional union\n", "{f}", .{diag});4185 try std.testing.expectFmt("1:1: error: expected optional union\n", "{f}", .{diag});
3551 }4186 }
...@@ -3555,7 +4190,7 @@ test "std.zon add pointers" {...@@ -3555,7 +4190,7 @@ test "std.zon add pointers" {
3555 defer diag.deinit(gpa);4190 defer diag.deinit(gpa);
3556 try std.testing.expectError(4191 try std.testing.expectError(
3557 error.ParseZon,4192 error.ParseZon,
3558 fromSliceAlloc(*const ?*const [3]u8, gpa, "true", &diag, .{}),4193 fromSliceAlloc(*const ?*const [3]u8, .{ .gpa = gpa, .source = "true", .diag = &diag }),
3559 );4194 );
3560 try std.testing.expectFmt("1:1: error: expected optional array\n", "{f}", .{diag});4195 try std.testing.expectFmt("1:1: error: expected optional array\n", "{f}", .{diag});
3561 }4196 }
...@@ -3565,7 +4200,7 @@ test "std.zon add pointers" {...@@ -3565,7 +4200,7 @@ test "std.zon add pointers" {
3565 defer diag.deinit(gpa);4200 defer diag.deinit(gpa);
3566 try std.testing.expectError(4201 try std.testing.expectError(
3567 error.ParseZon,4202 error.ParseZon,
3568 fromSliceAlloc(?[3]u8, gpa, "true", &diag, .{}),4203 fromSliceAlloc(?[3]u8, .{ .gpa = gpa, .source = "true", .diag = &diag }),
3569 );4204 );
3570 try std.testing.expectFmt("1:1: error: expected optional array\n", "{f}", .{diag});4205 try std.testing.expectFmt("1:1: error: expected optional array\n", "{f}", .{diag});
3571 }4206 }
...@@ -3575,7 +4210,7 @@ test "std.zon add pointers" {...@@ -3575,7 +4210,7 @@ test "std.zon add pointers" {
3575 defer diag.deinit(gpa);4210 defer diag.deinit(gpa);
3576 try std.testing.expectError(4211 try std.testing.expectError(
3577 error.ParseZon,4212 error.ParseZon,
3578 fromSliceAlloc(*const ?*const []u8, gpa, "true", &diag, .{}),4213 fromSliceAlloc(*const ?*const []u8, .{ .gpa = gpa, .source = "true", .diag = &diag }),
3579 );4214 );
3580 try std.testing.expectFmt("1:1: error: expected optional array\n", "{f}", .{diag});4215 try std.testing.expectFmt("1:1: error: expected optional array\n", "{f}", .{diag});
3581 }4216 }
...@@ -3585,7 +4220,7 @@ test "std.zon add pointers" {...@@ -3585,7 +4220,7 @@ test "std.zon add pointers" {
3585 defer diag.deinit(gpa);4220 defer diag.deinit(gpa);
3586 try std.testing.expectError(4221 try std.testing.expectError(
3587 error.ParseZon,4222 error.ParseZon,
3588 fromSliceAlloc(?[]u8, gpa, "true", &diag, .{}),4223 fromSliceAlloc(?[]u8, .{ .gpa = gpa, .source = "true", .diag = &diag }),
3589 );4224 );
3590 try std.testing.expectFmt("1:1: error: expected optional array\n", "{f}", .{diag});4225 try std.testing.expectFmt("1:1: error: expected optional array\n", "{f}", .{diag});
3591 }4226 }
...@@ -3595,7 +4230,7 @@ test "std.zon add pointers" {...@@ -3595,7 +4230,7 @@ test "std.zon add pointers" {
3595 defer diag.deinit(gpa);4230 defer diag.deinit(gpa);
3596 try std.testing.expectError(4231 try std.testing.expectError(
3597 error.ParseZon,4232 error.ParseZon,
3598 fromSliceAlloc(*const ?*const []const u8, gpa, "true", &diag, .{}),4233 fromSliceAlloc(*const ?*const []const u8, .{ .gpa = gpa, .source = "true", .diag = &diag }),
3599 );4234 );
3600 try std.testing.expectFmt("1:1: error: expected optional string\n", "{f}", .{diag});4235 try std.testing.expectFmt("1:1: error: expected optional string\n", "{f}", .{diag});
3601 }4236 }
...@@ -3605,7 +4240,7 @@ test "std.zon add pointers" {...@@ -3605,7 +4240,7 @@ test "std.zon add pointers" {
3605 defer diag.deinit(gpa);4240 defer diag.deinit(gpa);
3606 try std.testing.expectError(4241 try std.testing.expectError(
3607 error.ParseZon,4242 error.ParseZon,
3608 fromSliceAlloc(*const ?*const enum { foo }, gpa, "true", &diag, .{}),4243 fromSliceAlloc(*const ?*const enum { foo }, .{ .gpa = gpa, .source = "true", .diag = &diag }),
3609 );4244 );
3610 try std.testing.expectFmt("1:1: error: expected optional enum literal\n", "{f}", .{diag});4245 try std.testing.expectFmt("1:1: error: expected optional enum literal\n", "{f}", .{diag});
3611 }4246 }
...@@ -3622,7 +4257,11 @@ test "std.zon stop on node" {...@@ -3622,7 +4257,11 @@ test "std.zon stop on node" {
36224257
3623 var diag: Diagnostics = .{};4258 var diag: Diagnostics = .{};
3624 defer diag.deinit(gpa);4259 defer diag.deinit(gpa);
3625 const result = try fromSlice(Vec2, gpa, ".{ .x = 1.5, .y = 2.5 }", &diag, .{});4260 const result = try fromSlice(Vec2, .{
4261 .gpa = gpa,
4262 .source = ".{ .x = 1.5, .y = 2.5 }",
4263 .diag = &diag,
4264 });
3626 try std.testing.expectEqual(result.y, 2.5);4265 try std.testing.expectEqual(result.y, 2.5);
3627 try std.testing.expectEqual(Zoir.Node{ .float_literal = 1.5 }, result.x.get(diag.zoir));4266 try std.testing.expectEqual(Zoir.Node{ .float_literal = 1.5 }, result.x.get(diag.zoir));
3628 }4267 }
...@@ -3630,7 +4269,11 @@ test "std.zon stop on node" {...@@ -3630,7 +4269,11 @@ test "std.zon stop on node" {
3630 {4269 {
3631 var diag: Diagnostics = .{};4270 var diag: Diagnostics = .{};
3632 defer diag.deinit(gpa);4271 defer diag.deinit(gpa);
3633 const result = try fromSlice(Zoir.Node.Index, gpa, "1.23", &diag, .{});4272 const result = try fromSlice(Zoir.Node.Index, .{
4273 .gpa = gpa,
4274 .source = "1.23",
4275 .diag = &diag,
4276 });
3634 try std.testing.expectEqual(Zoir.Node{ .float_literal = 1.23 }, result.get(diag.zoir));4277 try std.testing.expectEqual(Zoir.Node{ .float_literal = 1.23 }, result.get(diag.zoir));
3635 }4278 }
3636}4279}
...@@ -3640,7 +4283,11 @@ test "std.zon no alloc" {...@@ -3640,7 +4283,11 @@ test "std.zon no alloc" {
36404283
3641 try std.testing.expectEqual(4284 try std.testing.expectEqual(
3642 [3]u8{ 1, 2, 3 },4285 [3]u8{ 1, 2, 3 },
3643 try fromSlice([3]u8, gpa, ".{ 1, 2, 3 }", null, .{}),4286 try fromSlice([3]u8, .{
4287 .gpa = gpa,
4288 .source = ".{ 1, 2, 3 }",
4289 .diag = null,
4290 }),
3644 );4291 );
36454292
3646 const Nested = struct { u8, u8, struct { u8, u8 } };4293 const Nested = struct { u8, u8, struct { u8, u8 } };
...@@ -3653,7 +4300,7 @@ test "std.zon no alloc" {...@@ -3653,7 +4300,7 @@ test "std.zon no alloc" {
36534300
3654 try std.testing.expectEqual(4301 try std.testing.expectEqual(
3655 Nested{ 1, 2, .{ 3, 4 } },4302 Nested{ 1, 2, .{ 3, 4 } },
3656 try fromZoir(Nested, ast, zoir, .root, null, .{}),4303 try fromZoir(Nested, .{ .ast = ast, .zoir = zoir, .diag = null }),
3657 );4304 );
3658}4305}
36594306
...@@ -3665,19 +4312,35 @@ test "std.zon errors without diagnostics" {...@@ -3665,19 +4312,35 @@ test "std.zon errors without diagnostics" {
3665 bar,4312 bar,
3666 baz,4313 baz,
3667 };4314 };
3668 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Enum, gpa, ".nothing", null, .{}));4315 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Enum, .{
4316 .gpa = gpa,
4317 .source = ".nothing",
4318 .diag = null,
4319 }));
36694320
3670 const Struct = struct {4321 const Struct = struct {
3671 name: []const u8,4322 name: []const u8,
3672 };4323 };
3673 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Struct, gpa, ".{ .name = \"Alice\", .age = 25 }", null, .{}));4324 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Struct, .{
4325 .gpa = gpa,
4326 .source = ".{ .name = \"Alice\", .age = 25 }",
4327 .diag = null,
4328 }));
36744329
3675 const Union = union(enum) {4330 const Union = union(enum) {
3676 x,4331 x,
3677 y: u32,4332 y: u32,
3678 };4333 };
3679 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Union, gpa, ".a", null, .{}));4334 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Union, .{
3680 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Union, gpa, ".{ .b = 8 }", null, .{}));4335 .gpa = gpa,
4336 .source = ".a",
4337 .diag = null,
4338 }));
4339 try std.testing.expectError(error.ParseZon, fromSliceAlloc(Union, .{
4340 .gpa = gpa,
4341 .source = ".{ .b = 8 }",
4342 .diag = null,
4343 }));
3681}4344}
36824345
3683test "std.zon aligned pointers" {4346test "std.zon aligned pointers" {
...@@ -3691,13 +4354,11 @@ test "std.zon aligned pointers" {...@@ -3691,13 +4354,11 @@ test "std.zon aligned pointers" {
3691 const expected: Foo = .{4354 const expected: Foo = .{
3692 .inner = &n,4355 .inner = &n,
3693 };4356 };
3694 const found = try fromSliceAlloc(4357 const found = try fromSliceAlloc(Foo, .{
3695 Foo,4358 .gpa = gpa,
3696 gpa,4359 .source = ".{ .inner = 10 }",
3697 ".{ .inner = 10 }",4360 .diag = null,
3698 null,4361 });
3699 .{},
3700 );
3701 defer free(gpa, found);4362 defer free(gpa, found);
3702 try std.testing.expectEqualDeep(expected.inner, found.inner);4363 try std.testing.expectEqualDeep(expected.inner, found.inner);
3703}4364}
...@@ -3743,94 +4404,78 @@ test "std.zon update" {...@@ -3743,94 +4404,78 @@ test "std.zon update" {
3743 };4404 };
3744 defer free(gpa, found);4405 defer free(gpa, found);
37454406
3746 try updateFromSliceAlloc(4407 try updateFromSliceAlloc(MyStruct, .{
3747 MyStruct,4408 .gpa = gpa,
3748 gpa,4409 .value = &found,
3749 &found,4410 .source = ".{}",
3750 ".{}",4411 .diag = null,
3751 null,4412 });
3752 .{},
3753 );
3754 try std.testing.expectEqualDeep(expected, found);4413 try std.testing.expectEqualDeep(expected, found);
37554414
3756 try updateFromSliceAlloc(4415 try updateFromSliceAlloc(MyStruct, .{
3757 MyStruct,4416 .gpa = gpa,
3758 gpa,4417 .value = &found,
3759 &found,4418 .source = ".{ .bar = false }",
3760 ".{ .bar = false }",4419 .diag = null,
3761 null,4420 });
3762 .{},
3763 );
3764 expected.bar = false;4421 expected.bar = false;
3765 try std.testing.expectEqualDeep(expected, found);4422 try std.testing.expectEqualDeep(expected, found);
37664423
3767 try updateFromSliceAlloc(4424 try updateFromSliceAlloc(MyStruct, .{
3768 MyStruct,4425 .gpa = gpa,
3769 gpa,4426 .value = &found,
3770 &found,4427 .source = ".{ .baz = .{ .a = .{ 2, 4 } } }",
3771 ".{ .baz = .{ .a = .{ 2, 4 } } }",4428 .diag = null,
3772 null,4429 });
3773 .{},
3774 );
3775 expected.baz.a[0] = 2;4430 expected.baz.a[0] = 2;
3776 expected.baz.a[1] = 4;4431 expected.baz.a[1] = 4;
3777 try std.testing.expectEqualDeep(expected, found);4432 try std.testing.expectEqualDeep(expected, found);
37784433
3779 try updateFromSliceAlloc(4434 try updateFromSliceAlloc(MyStruct, .{
3780 MyStruct,4435 .gpa = gpa,
3781 gpa,4436 .value = &found,
3782 &found,4437 .source = ".{ .foo = 11, .baz = .{ .b = .d } }",
3783 ".{ .foo = 11, .baz = .{ .b = .d } }",4438 .diag = null,
3784 null,4439 });
3785 .{},
3786 );
3787 expected.foo = 11;4440 expected.foo = 11;
3788 expected.baz.b = .d;4441 expected.baz.b = .d;
3789 try std.testing.expectEqualDeep(expected, found);4442 try std.testing.expectEqualDeep(expected, found);
37904443
3791 try updateFromSliceAlloc(4444 try updateFromSliceAlloc(MyStruct, .{
3792 MyStruct,4445 .gpa = gpa,
3793 gpa,4446 .value = &found,
3794 &found,4447 .source = ".{ .optional = 10 }",
3795 ".{ .optional = 10 }",4448 .diag = null,
3796 null,4449 });
3797 .{},
3798 );
3799 expected.optional = 10;4450 expected.optional = 10;
3800 try std.testing.expectEqualDeep(expected, found);4451 try std.testing.expectEqualDeep(expected, found);
38014452
3802 try updateFromSliceAlloc(4453 try updateFromSliceAlloc(MyStruct, .{
3803 MyStruct,4454 .gpa = gpa,
3804 gpa,4455 .value = &found,
3805 &found,4456 .source = ".{ .optional = null }",
3806 ".{ .optional = null }",4457 .diag = null,
3807 null,4458 });
3808 .{},
3809 );
3810 expected.optional = null;4459 expected.optional = null;
3811 try std.testing.expectEqualDeep(expected, found);4460 try std.testing.expectEqualDeep(expected, found);
38124461
3813 try updateFromSliceAlloc(4462 try updateFromSliceAlloc(MyStruct, .{
3814 MyStruct,4463 .gpa = gpa,
3815 gpa,4464 .value = &found,
3816 &found,4465 .source = ".{ .ptr = .{ .x = 10, .y = 20, .z = 30 } }",
3817 ".{ .ptr = .{ .x = 10, .y = 20, .z = 30 } }",4466 .diag = null,
3818 null,4467 });
3819 .{},
3820 );
3821 expected.ptr.x = 10;4468 expected.ptr.x = 10;
3822 expected.ptr.y = 20;4469 expected.ptr.y = 20;
3823 expected.ptr.z = 30;4470 expected.ptr.z = 30;
3824 try std.testing.expectEqualDeep(expected, found);4471 try std.testing.expectEqualDeep(expected, found);
38254472
3826 try updateFromSliceAlloc(4473 try updateFromSliceAlloc(MyStruct, .{
3827 MyStruct,4474 .gpa = gpa,
3828 gpa,4475 .value = &found,
3829 &found,4476 .source = ".{ .str = \"foo\" }",
3830 ".{ .str = \"foo\" }",4477 .diag = null,
3831 null,4478 });
3832 .{},
3833 );
3834 gpa.free(expected.str);4479 gpa.free(expected.str);
3835 expected.str = gpa.dupe(u8, "foo") catch @panic("oom");4480 expected.str = gpa.dupe(u8, "foo") catch @panic("oom");
3836 try std.testing.expectEqualDeep(expected, found);4481 try std.testing.expectEqualDeep(expected, found);
...@@ -3854,19 +4499,40 @@ test "std.zon variants" {...@@ -3854,19 +4499,40 @@ test "std.zon variants" {
3854 defer zoir.deinit(gpa);4499 defer zoir.deinit(gpa);
38554500
3856 var curr = start;4501 var curr = start;
3857 try updateFromSlice(Struct, gpa, &curr, ".{ .a = 100 }", null, .{});4502 try updateFromSlice(Struct, .{
4503 .gpa = gpa,
4504 .value = &curr,
4505 .source = ".{ .a = 100 }",
4506 .diag = null,
4507 });
3858 try std.testing.expectEqual(end, curr);4508 try std.testing.expectEqual(end, curr);
38594509
3860 curr = start;4510 curr = start;
3861 try updateFromSliceAlloc(Struct, gpa, &curr, ".{ .a = 100 }", null, .{});4511 try updateFromSliceAlloc(Struct, .{
4512 .gpa = gpa,
4513 .value = &curr,
4514 .source = ".{ .a = 100 }",
4515 .diag = null,
4516 });
3862 try std.testing.expectEqual(end, curr);4517 try std.testing.expectEqual(end, curr);
38634518
3864 curr = start;4519 curr = start;
3865 try updateFromZoir(Struct, &curr, ast, zoir, .root, null, .{});4520 try updateFromZoir(Struct, .{
4521 .ast = ast,
4522 .value = &curr,
4523 .zoir = zoir,
4524 .diag = null,
4525 });
3866 try std.testing.expectEqual(end, curr);4526 try std.testing.expectEqual(end, curr);
38674527
3868 curr = start;4528 curr = start;
3869 try updateFromZoirAlloc(Struct, gpa, &curr, ast, zoir, .root, null, .{});4529 try updateFromZoirAlloc(Struct, .{
4530 .gpa = gpa,
4531 .value = &curr,
4532 .ast = ast,
4533 .zoir = zoir,
4534 .diag = null,
4535 });
3870 try std.testing.expectEqual(end, curr);4536 try std.testing.expectEqual(end, curr);
3871 }4537 }
38724538
...@@ -3879,18 +4545,35 @@ test "std.zon variants" {...@@ -3879,18 +4545,35 @@ test "std.zon variants" {
38794545
3880 try std.testing.expectEqual(4546 try std.testing.expectEqual(
3881 end,4547 end,
3882 try fromSlice(Struct, gpa, ".{ .a = 100, .b = 20 }", null, .{}),4548 try fromSlice(Struct, .{
4549 .gpa = gpa,
4550 .source = ".{ .a = 100, .b = 20 }",
4551 .diag = null,
4552 }),
3883 );4553 );
3884 try std.testing.expectEqual(4554 try std.testing.expectEqual(
3885 end,4555 end,
3886 try fromSliceAlloc(Struct, gpa, ".{ .a = 100, .b = 20 }", null, .{}),4556 try fromSliceAlloc(Struct, .{
4557 .gpa = gpa,
4558 .source = ".{ .a = 100, .b = 20 }",
4559 .diag = null,
4560 }),
3887 );4561 );
3888 try std.testing.expectEqual(4562 try std.testing.expectEqual(
3889 try fromZoir(Struct, ast, zoir, .root, null, .{}),4563 try fromZoir(Struct, .{
4564 .ast = ast,
4565 .zoir = zoir,
4566 .diag = null,
4567 }),
3890 end,4568 end,
3891 );4569 );
3892 try std.testing.expectEqual(4570 try std.testing.expectEqual(
3893 try fromZoirAlloc(Struct, gpa, ast, zoir, .root, null, .{}),4571 try fromZoirAlloc(Struct, .{
4572 .gpa = gpa,
4573 .ast = ast,
4574 .zoir = zoir,
4575 .diag = null,
4576 }),
3894 end,4577 end,
3895 );4578 );
3896 }4579 }