From 3979d32a1d399e2a8f5d967b392160a3dd099878 Mon Sep 17 00:00:00 2001 From: Simon Hartcher Date: Thu, 5 Jun 2025 13:47:37 +1000 Subject: [PATCH] fix(json): need to write null when structure is null --- codegen/src/serialization/json.zig | 2 + src/aws.zig | 69 ++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/codegen/src/serialization/json.zig b/codegen/src/serialization/json.zig index 105cef2..dc5e5ea 100644 --- a/codegen/src/serialization/json.zig +++ b/codegen/src/serialization/json.zig @@ -213,6 +213,8 @@ fn writeStructureJson(params: WriteMemberJsonParams, writer: std.io.AnyWriter) ! try writer.writeAll("try jw.endObject();\n"); if (is_optional) { + try writer.writeAll("} else {\n"); + try writer.writeAll("try jw.write(null);\n"); try writer.writeAll("}\n"); } } diff --git a/src/aws.zig b/src/aws.zig index c4ddb3d..822c8cc 100644 --- a/src/aws.zig +++ b/src/aws.zig @@ -2703,30 +2703,53 @@ test "jsonStringify" { } test "jsonStringify nullable object" { - const request = services.lambda.CreateAliasRequest{ - .function_name = "foo", - .function_version = "bar", - .name = "baz", - .routing_config = services.lambda.AliasRoutingConfiguration{ - .additional_version_weights = null, - }, - }; + // structure is not null + { + const request = services.lambda.CreateAliasRequest{ + .function_name = "foo", + .function_version = "bar", + .name = "baz", + .routing_config = services.lambda.AliasRoutingConfiguration{ + .additional_version_weights = null, + }, + }; - const request_json = try std.json.stringifyAlloc(std.testing.allocator, request, .{}); - defer std.testing.allocator.free(request_json); + const request_json = try std.json.stringifyAlloc(std.testing.allocator, request, .{}); + defer std.testing.allocator.free(request_json); - const json_parsed = try std.json.parseFromSlice(struct { - FunctionName: []const u8, - FunctionVersion: []const u8, - Name: []const u8, - RoutingConfig: struct { - AdditionalVersionWeights: ?struct {}, - }, - }, testing.allocator, request_json, .{ .ignore_unknown_fields = true }); - defer json_parsed.deinit(); + const json_parsed = try std.json.parseFromSlice(struct { + FunctionName: []const u8, + FunctionVersion: []const u8, + Name: []const u8, + RoutingConfig: struct { + AdditionalVersionWeights: ?struct {}, + }, + }, testing.allocator, request_json, .{ .ignore_unknown_fields = true }); + defer json_parsed.deinit(); - try testing.expectEqualStrings("foo", json_parsed.value.FunctionName); - try testing.expectEqualStrings("bar", json_parsed.value.FunctionVersion); - try testing.expectEqualStrings("baz", json_parsed.value.Name); - try testing.expectEqual(null, json_parsed.value.RoutingConfig.AdditionalVersionWeights); + try testing.expectEqualStrings("foo", json_parsed.value.FunctionName); + try testing.expectEqualStrings("bar", json_parsed.value.FunctionVersion); + try testing.expectEqualStrings("baz", json_parsed.value.Name); + try testing.expectEqual(null, json_parsed.value.RoutingConfig.AdditionalVersionWeights); + } + + // structure is null + { + const request = services.kms.DecryptRequest{ + .key_id = "foo", + .ciphertext_blob = "bar", + }; + + const request_json = try std.json.stringifyAlloc(std.testing.allocator, request, .{}); + defer std.testing.allocator.free(request_json); + + const json_parsed = try std.json.parseFromSlice(struct { + KeyId: []const u8, + CiphertextBlob: []const u8, + }, testing.allocator, request_json, .{ .ignore_unknown_fields = true }); + defer json_parsed.deinit(); + + try testing.expectEqualStrings("foo", json_parsed.value.KeyId); + try testing.expectEqualStrings("bar", json_parsed.value.CiphertextBlob); + } }