Skip to content

Commit 838f0ff

Browse files
committed
fix json serialization for null/empty maps
1 parent acd6589 commit 838f0ff

File tree

2 files changed

+70
-2
lines changed

2 files changed

+70
-2
lines changed

codegen/src/json.zig

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,31 @@ const std = @import("std");
44
pub fn serializeMap(map: anytype, key: []const u8, options: anytype, out_stream: anytype) !bool {
55
if (@typeInfo(@TypeOf(map)) == .optional) {
66
if (map == null)
7-
return true
7+
return false
88
else
99
return serializeMapInternal(map.?, key, options, out_stream);
1010
}
1111
return serializeMapInternal(map, key, options, out_stream);
1212
}
1313

1414
fn serializeMapInternal(map: anytype, key: []const u8, options: anytype, out_stream: anytype) !bool {
15-
if (map.len == 0) return true;
15+
if (map.len == 0) {
16+
var child_options = options;
17+
if (child_options.whitespace) |*child_ws|
18+
child_ws.indent_level += 1;
19+
20+
try out_stream.writeByte('"');
21+
try out_stream.writeAll(key);
22+
_ = try out_stream.write("\":");
23+
if (options.whitespace) |ws| {
24+
if (ws.separator) {
25+
try out_stream.writeByte(' ');
26+
}
27+
}
28+
try out_stream.writeByte('{');
29+
try out_stream.writeByte('}');
30+
return true;
31+
}
1632
// TODO: Map might be [][]struct{key, value} rather than []struct{key, value}
1733
var child_options = options;
1834
if (child_options.whitespace) |*child_ws|

src/aws.zig

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,58 @@ test "custom serialization for map objects" {
13061306
, buffer.items);
13071307
}
13081308

1309+
test "proper serialization for kms" {
1310+
// Github issue #8
1311+
// https://github.com/elerch/aws-sdk-for-zig/issues/8
1312+
const allocator = std.testing.allocator;
1313+
var buffer = std.ArrayList(u8).init(allocator);
1314+
defer buffer.deinit();
1315+
const req = services.kms.encrypt.Request{
1316+
.encryption_algorithm = "SYMMETRIC_DEFAULT",
1317+
// Since encryption_context is not null, we expect "{}" to be the value
1318+
// here, not "[]", because this is our special AWS map pattern
1319+
.encryption_context = &.{},
1320+
.key_id = "42",
1321+
.plaintext = "foo",
1322+
.dry_run = false,
1323+
.grant_tokens = &[_][]const u8{},
1324+
};
1325+
try json.stringify(req, .{ .whitespace = .{} }, buffer.writer());
1326+
try std.testing.expectEqualStrings(
1327+
\\{
1328+
\\ "KeyId": "42",
1329+
\\ "Plaintext": "foo",
1330+
\\ "EncryptionContext": {},
1331+
\\ "GrantTokens": [],
1332+
\\ "EncryptionAlgorithm": "SYMMETRIC_DEFAULT",
1333+
\\ "DryRun": false
1334+
\\}
1335+
, buffer.items);
1336+
1337+
var buffer_null = std.ArrayList(u8).init(allocator);
1338+
defer buffer_null.deinit();
1339+
const req_null = services.kms.encrypt.Request{
1340+
.encryption_algorithm = "SYMMETRIC_DEFAULT",
1341+
// Since encryption_context here *IS* null, we expect simply "null" to be the value
1342+
.encryption_context = null,
1343+
.key_id = "42",
1344+
.plaintext = "foo",
1345+
.dry_run = false,
1346+
.grant_tokens = &[_][]const u8{},
1347+
};
1348+
try json.stringify(req_null, .{ .whitespace = .{} }, buffer_null.writer());
1349+
try std.testing.expectEqualStrings(
1350+
\\{
1351+
\\ "KeyId": "42",
1352+
\\ "Plaintext": "foo",
1353+
\\ "EncryptionContext": null,
1354+
\\ "GrantTokens": [],
1355+
\\ "EncryptionAlgorithm": "SYMMETRIC_DEFAULT",
1356+
\\ "DryRun": false
1357+
\\}
1358+
, buffer_null.items);
1359+
}
1360+
13091361
test "REST Json v1 builds proper queries" {
13101362
const allocator = std.testing.allocator;
13111363
const svs = Services(.{.lambda}){};

0 commit comments

Comments
 (0)