| ... | ... | @@ -287,7 +287,7 @@ pub fn innerParse( |
| 287 | 287 | const field_name = switch (name_token.?) { |
| 288 | 288 | inline .string, .allocated_string => |slice| slice, |
| 289 | 289 | else => { |
| 290 | | if (options.diagnostics) |diag| diag.recordContext("tagged union requires a field to identify the active tag"); |
| 290 | if (options.diagnostics) |diag| diag.setMessage("tagged union requires a field to identify the active tag"); |
| 291 | 291 | return error.MissingField; |
| 292 | 292 | }, |
| 293 | 293 | }; |
| ... | ... | @@ -305,7 +305,7 @@ pub fn innerParse( |
| 305 | 305 | else => |t| return typeError(options.diagnostics, t, "void payload ('{}')"), |
| 306 | 306 | } |
| 307 | 307 | if (.object_end != try source.next()) { |
| 308 | | if (options.diagnostics) |diag| diag.recordContext("void payload '{}' should have no fields"); |
| 308 | if (options.diagnostics) |diag| diag.setMessage("void payload '{}' should have no fields"); |
| 309 | 309 | return error.UnknownField; |
| 310 | 310 | } |
| 311 | 311 | result = @unionInit(T, u_field.name, {}); |
| ... | ... | @@ -317,12 +317,12 @@ pub fn innerParse( |
| 317 | 317 | } |
| 318 | 318 | } else { |
| 319 | 319 | // Didn't match anything. |
| 320 | | if (options.diagnostics) |diag| diag.recordContext("unrecognized tag name"); |
| 320 | if (options.diagnostics) |diag| diag.setMessage("unrecognized tag name"); |
| 321 | 321 | return error.UnknownField; |
| 322 | 322 | } |
| 323 | 323 | |
| 324 | 324 | if (.object_end != try source.next()) { |
| 325 | | if (options.diagnostics) |diag| diag.recordContext("tagged union requires only one field"); |
| 325 | if (options.diagnostics) |diag| diag.setMessage("tagged union requires only one field"); |
| 326 | 326 | return error.UnknownField; |
| 327 | 327 | } |
| 328 | 328 | |
| ... | ... | @@ -339,7 +339,7 @@ pub fn innerParse( |
| 339 | 339 | var r: T = undefined; |
| 340 | 340 | inline for (0..structInfo.fields.len) |i| { |
| 341 | 341 | if (.array_end == try source.peekNextTokenType()) { |
| 342 | | if (options.diagnostics) |diag| diag.recordContext(std.fmt.comptimePrint( |
| 342 | if (options.diagnostics) |diag| diag.setMessage(std.fmt.comptimePrint( |
| 343 | 343 | "tuple too short. expected length: {}", |
| 344 | 344 | .{structInfo.fields.len}, |
| 345 | 345 | )); |
| ... | ... | @@ -349,7 +349,7 @@ pub fn innerParse( |
| 349 | 349 | } |
| 350 | 350 | |
| 351 | 351 | if (.array_end != try source.next()) { |
| 352 | | if (options.diagnostics) |diag| diag.recordContext(std.fmt.comptimePrint( |
| 352 | if (options.diagnostics) |diag| diag.setMessage(std.fmt.comptimePrint( |
| 353 | 353 | "tuple too long. expected length: {}", |
| 354 | 354 | .{structInfo.fields.len}, |
| 355 | 355 | )); |
| ... | ... | @@ -398,7 +398,7 @@ pub fn innerParse( |
| 398 | 398 | break; |
| 399 | 399 | }, |
| 400 | 400 | .@"error" => { |
| 401 | | if (options.diagnostics) |diag| diag.recordContext("duplicate field name: " ++ field.name); |
| 401 | if (options.diagnostics) |diag| diag.setMessage("duplicate field name: " ++ field.name); |
| 402 | 402 | return error.DuplicateField; |
| 403 | 403 | }, |
| 404 | 404 | .use_last => {}, |
| ... | ... | @@ -414,7 +414,7 @@ pub fn innerParse( |
| 414 | 414 | if (options.ignore_unknown_fields) { |
| 415 | 415 | try source.skipValue(); |
| 416 | 416 | } else { |
| 417 | | if (options.diagnostics) |diag| diag.recordContext("unrecognized field name"); |
| 417 | if (options.diagnostics) |diag| diag.setMessage("unrecognized field name"); |
| 418 | 418 | return error.UnknownField; |
| 419 | 419 | } |
| 420 | 420 | } |
| ... | ... | @@ -438,32 +438,54 @@ pub fn innerParse( |
| 438 | 438 | while (true) { |
| 439 | 439 | switch (try source.next()) { |
| 440 | 440 | .string => |slice| { |
| 441 | | if (i + slice.len != r.len) return error.LengthMismatch; |
| 441 | if (i + slice.len > r.len) { |
| 442 | if (options.diagnostics) |diag| diag.setMessage(std.fmt.comptimePrint("string too long for fixed length array. expected length: {}", .{r.len})); |
| 443 | return error.LengthMismatch; |
| 444 | } |
| 445 | if (i + slice.len < r.len) { |
| 446 | if (options.diagnostics) |diag| diag.setMessage(std.fmt.comptimePrint("string too short for fixed length array. expected length: {}", .{r.len})); |
| 447 | return error.LengthMismatch; |
| 448 | } |
| 442 | 449 | @memcpy(r[i..][0..slice.len], slice); |
| 443 | 450 | break; |
| 444 | 451 | }, |
| 445 | 452 | .partial_string => |slice| { |
| 446 | | if (i + slice.len > r.len) return error.LengthMismatch; |
| 453 | if (i + slice.len > r.len) { |
| 454 | if (options.diagnostics) |diag| diag.setMessage(std.fmt.comptimePrint("string too long for fixed length array. expected length: {}", .{r.len})); |
| 455 | return error.LengthMismatch; |
| 456 | } |
| 447 | 457 | @memcpy(r[i..][0..slice.len], slice); |
| 448 | 458 | i += slice.len; |
| 449 | 459 | }, |
| 450 | 460 | .partial_string_escaped_1 => |arr| { |
| 451 | | if (i + arr.len > r.len) return error.LengthMismatch; |
| 461 | if (i + arr.len > r.len) { |
| 462 | if (options.diagnostics) |diag| diag.setMessage(std.fmt.comptimePrint("string too long for fixed length array. expected length: {}", .{r.len})); |
| 463 | return error.LengthMismatch; |
| 464 | } |
| 452 | 465 | @memcpy(r[i..][0..arr.len], arr[0..]); |
| 453 | 466 | i += arr.len; |
| 454 | 467 | }, |
| 455 | 468 | .partial_string_escaped_2 => |arr| { |
| 456 | | if (i + arr.len > r.len) return error.LengthMismatch; |
| 469 | if (i + arr.len > r.len) { |
| 470 | if (options.diagnostics) |diag| diag.setMessage(std.fmt.comptimePrint("string too long for fixed length array. expected length: {}", .{r.len})); |
| 471 | return error.LengthMismatch; |
| 472 | } |
| 457 | 473 | @memcpy(r[i..][0..arr.len], arr[0..]); |
| 458 | 474 | i += arr.len; |
| 459 | 475 | }, |
| 460 | 476 | .partial_string_escaped_3 => |arr| { |
| 461 | | if (i + arr.len > r.len) return error.LengthMismatch; |
| 477 | if (i + arr.len > r.len) { |
| 478 | if (options.diagnostics) |diag| diag.setMessage(std.fmt.comptimePrint("string too long for fixed length array. expected length: {}", .{r.len})); |
| 479 | return error.LengthMismatch; |
| 480 | } |
| 462 | 481 | @memcpy(r[i..][0..arr.len], arr[0..]); |
| 463 | 482 | i += arr.len; |
| 464 | 483 | }, |
| 465 | 484 | .partial_string_escaped_4 => |arr| { |
| 466 | | if (i + arr.len > r.len) return error.LengthMismatch; |
| 485 | if (i + arr.len > r.len) { |
| 486 | if (options.diagnostics) |diag| diag.setMessage(std.fmt.comptimePrint("string too long for fixed length array. expected length: {}", .{r.len})); |
| 487 | return error.LengthMismatch; |
| 488 | } |
| 467 | 489 | @memcpy(r[i..][0..arr.len], arr[0..]); |
| 468 | 490 | i += arr.len; |
| 469 | 491 | }, |
| ... | ... | @@ -568,11 +590,17 @@ fn internalParseArray( |
| 568 | 590 | var r: T = undefined; |
| 569 | 591 | var i: usize = 0; |
| 570 | 592 | while (i < len) : (i += 1) { |
| 571 | | if (.array_end == try source.peekNextTokenType()) return error.LengthMismatch; |
| 593 | if (.array_end == try source.peekNextTokenType()) { |
| 594 | if (options.diagnostics) |diag| diag.setMessage(std.fmt.comptimePrint("not enough items for fixed length array. expected length: {}", .{len})); |
| 595 | return error.LengthMismatch; |
| 596 | } |
| 572 | 597 | r[i] = try innerParse(Child, allocator, source, options); |
| 573 | 598 | } |
| 574 | 599 | |
| 575 | | if (.array_end != try source.next()) return error.LengthMismatch; |
| 600 | if (.array_end != try source.next()) { |
| 601 | if (options.diagnostics) |diag| diag.setMessage(std.fmt.comptimePrint("too many items for fixed length array. expected length: {}", .{len})); |
| 602 | return error.LengthMismatch; |
| 603 | } |
| 576 | 604 | |
| 577 | 605 | return r; |
| 578 | 606 | } |
| ... | ... | @@ -622,7 +650,7 @@ fn typeError(diagnostics: ?*Diagnostics, token: anytype, comptime expected: []co |
| 622 | 650 | .array_end => unreachable, // type errors happen at the start of a value. |
| 623 | 651 | .end_of_document => unreachable, // type errors happen at the start of a value. |
| 624 | 652 | }; |
| 625 | | diag.recordContext(s); |
| 653 | diag.setMessage(s); |
| 626 | 654 | } |
| 627 | 655 | return error.UnexpectedToken; |
| 628 | 656 | } |
| ... | ... | @@ -880,7 +908,7 @@ fn fillDefaultStructValues(comptime T: type, options: ParseOptions, r: *T, field |
| 880 | 908 | const default = @as(*align(1) const field.type, @ptrCast(default_ptr)).*; |
| 881 | 909 | @field(r, field.name) = default; |
| 882 | 910 | } else { |
| 883 | | if (options.diagnostics) |diag| diag.recordContext("missing field: " ++ @typeName(T) ++ "." ++ field.name); |
| 911 | if (options.diagnostics) |diag| diag.setMessage("missing field: " ++ @typeName(T) ++ "." ++ field.name); |
| 884 | 912 | return error.MissingField; |
| 885 | 913 | } |
| 886 | 914 | } |