fix most test compilation errors
This commit is contained in:
parent
8d399cb8a6
commit
1170ba99fc
3 changed files with 142 additions and 129 deletions
46
src/aws.zig
46
src/aws.zig
|
@ -1412,14 +1412,14 @@ fn typeForField(comptime T: type, comptime field_name: []const u8) !type {
|
|||
|
||||
test "custom serialization for map objects" {
|
||||
const allocator = std.testing.allocator;
|
||||
var buffer = std.ArrayList(u8).init(allocator);
|
||||
var buffer = std.Io.Writer.Allocating.init(allocator);
|
||||
defer buffer.deinit();
|
||||
var tags = try std.ArrayList(@typeInfo(try typeForField(services.lambda.tag_resource.Request, "tags")).pointer.child).initCapacity(allocator, 2);
|
||||
defer tags.deinit();
|
||||
defer tags.deinit(allocator);
|
||||
tags.appendAssumeCapacity(.{ .key = "Foo", .value = "Bar" });
|
||||
tags.appendAssumeCapacity(.{ .key = "Baz", .value = "Qux" });
|
||||
const req = services.lambda.TagResourceRequest{ .resource = "hello", .tags = tags.items };
|
||||
try std.json.stringify(req, .{ .whitespace = .indent_4 }, buffer.writer());
|
||||
try buffer.writer.print("{f}", .{std.json.fmt(req, .{ .whitespace = .indent_4 })});
|
||||
|
||||
const parsed_body = try std.json.parseFromSlice(struct {
|
||||
Resource: []const u8,
|
||||
|
@ -1427,7 +1427,7 @@ test "custom serialization for map objects" {
|
|||
Foo: []const u8,
|
||||
Baz: []const u8,
|
||||
},
|
||||
}, testing.allocator, buffer.items, .{});
|
||||
}, testing.allocator, buffer.written(), .{});
|
||||
defer parsed_body.deinit();
|
||||
|
||||
try testing.expectEqualStrings("hello", parsed_body.value.Resource);
|
||||
|
@ -1439,7 +1439,7 @@ test "proper serialization for kms" {
|
|||
// Github issue #8
|
||||
// https://github.com/elerch/aws-sdk-for-zig/issues/8
|
||||
const allocator = std.testing.allocator;
|
||||
var buffer = std.ArrayList(u8).init(allocator);
|
||||
var buffer = std.Io.Writer.Allocating.init(allocator);
|
||||
defer buffer.deinit();
|
||||
const req = services.kms.encrypt.Request{
|
||||
.encryption_algorithm = "SYMMETRIC_DEFAULT",
|
||||
|
@ -1451,7 +1451,7 @@ test "proper serialization for kms" {
|
|||
.dry_run = false,
|
||||
.grant_tokens = &[_][]const u8{},
|
||||
};
|
||||
try std.json.stringify(req, .{ .whitespace = .indent_4 }, buffer.writer());
|
||||
try buffer.writer.print("{f}", .{std.json.fmt(req, .{ .whitespace = .indent_4 })});
|
||||
|
||||
{
|
||||
const parsed_body = try std.json.parseFromSlice(struct {
|
||||
|
@ -1461,7 +1461,7 @@ test "proper serialization for kms" {
|
|||
GrantTokens: [][]const u8,
|
||||
EncryptionAlgorithm: []const u8,
|
||||
DryRun: bool,
|
||||
}, testing.allocator, buffer.items, .{});
|
||||
}, testing.allocator, buffer.written(), .{});
|
||||
defer parsed_body.deinit();
|
||||
|
||||
try testing.expectEqualStrings("42", parsed_body.value.KeyId);
|
||||
|
@ -1471,7 +1471,7 @@ test "proper serialization for kms" {
|
|||
try testing.expectEqual(false, parsed_body.value.DryRun);
|
||||
}
|
||||
|
||||
var buffer_null = std.ArrayList(u8).init(allocator);
|
||||
var buffer_null = std.Io.Writer.Allocating.init(allocator);
|
||||
defer buffer_null.deinit();
|
||||
const req_null = services.kms.encrypt.Request{
|
||||
.encryption_algorithm = "SYMMETRIC_DEFAULT",
|
||||
|
@ -1483,7 +1483,7 @@ test "proper serialization for kms" {
|
|||
.grant_tokens = &[_][]const u8{},
|
||||
};
|
||||
|
||||
try std.json.stringify(req_null, .{ .whitespace = .indent_4 }, buffer_null.writer());
|
||||
try buffer_null.writer.print("{f}", .{std.json.fmt(req_null, .{ .whitespace = .indent_4 })});
|
||||
|
||||
{
|
||||
const parsed_body = try std.json.parseFromSlice(struct {
|
||||
|
@ -1493,7 +1493,7 @@ test "proper serialization for kms" {
|
|||
GrantTokens: [][]const u8,
|
||||
EncryptionAlgorithm: []const u8,
|
||||
DryRun: bool,
|
||||
}, testing.allocator, buffer_null.items, .{});
|
||||
}, testing.allocator, buffer_null.written(), .{});
|
||||
defer parsed_body.deinit();
|
||||
|
||||
try testing.expectEqualStrings("42", parsed_body.value.KeyId);
|
||||
|
@ -1541,8 +1541,8 @@ test "REST Json v1 serializes lists in queries" {
|
|||
}
|
||||
test "REST Json v1 buildpath substitutes" {
|
||||
const allocator = std.testing.allocator;
|
||||
var al = std.ArrayList([]const u8).init(allocator);
|
||||
defer al.deinit();
|
||||
var al = std.ArrayList([]const u8){};
|
||||
defer al.deinit(allocator);
|
||||
const svs = Services(.{.lambda}){};
|
||||
const request = svs.lambda.list_functions.Request{
|
||||
.max_items = 1,
|
||||
|
@ -1554,8 +1554,8 @@ test "REST Json v1 buildpath substitutes" {
|
|||
}
|
||||
test "REST Json v1 buildpath handles restricted characters" {
|
||||
const allocator = std.testing.allocator;
|
||||
var al = std.ArrayList([]const u8).init(allocator);
|
||||
defer al.deinit();
|
||||
var al = std.ArrayList([]const u8){};
|
||||
defer al.deinit(allocator);
|
||||
const svs = Services(.{.lambda}){};
|
||||
const request = svs.lambda.list_functions.Request{
|
||||
.marker = ":",
|
||||
|
@ -1571,7 +1571,7 @@ test "basic json request serialization" {
|
|||
const request = svs.dynamo_db.list_tables.Request{
|
||||
.limit = 1,
|
||||
};
|
||||
var buffer = std.ArrayList(u8).init(allocator);
|
||||
var buffer = std.Io.Writer.Allocating.init(allocator);
|
||||
defer buffer.deinit();
|
||||
|
||||
// The transformer needs to allocate stuff out of band, but we
|
||||
|
@ -1583,13 +1583,13 @@ test "basic json request serialization" {
|
|||
// for a boxed member with no observable difference." But we're
|
||||
// seeing a lot of differences here between spec and reality
|
||||
//
|
||||
try std.json.stringify(request, .{ .whitespace = .indent_4 }, buffer.writer());
|
||||
try buffer.writer.print("{f}", .{std.json.fmt(request, .{ .whitespace = .indent_4 })});
|
||||
try std.testing.expectEqualStrings(
|
||||
\\{
|
||||
\\ "ExclusiveStartTableName": null,
|
||||
\\ "Limit": 1
|
||||
\\}
|
||||
, buffer.items);
|
||||
, buffer.written());
|
||||
}
|
||||
test "layer object only" {
|
||||
const TestResponse = struct {
|
||||
|
@ -2291,7 +2291,7 @@ test "rest_json_1_work_with_lambda: lambda tagResource (only), to excercise zig
|
|||
const options = try test_harness.start();
|
||||
const lambda = (Services(.{.lambda}){}).lambda;
|
||||
var tags = try std.ArrayList(@typeInfo(try typeForField(lambda.tag_resource.Request, "tags")).pointer.child).initCapacity(allocator, 1);
|
||||
defer tags.deinit();
|
||||
defer tags.deinit(allocator);
|
||||
tags.appendAssumeCapacity(.{ .key = "Foo", .value = "Bar" });
|
||||
const req = services.lambda.tag_resource.Request{ .resource = "arn:aws:lambda:us-west-2:550620852718:function:awsome-lambda-LambdaStackawsomeLambda", .tags = tags.items };
|
||||
const call = try Request(lambda.tag_resource).call(req, options);
|
||||
|
@ -2674,7 +2674,7 @@ test "jsonStringify: structure + enums" {
|
|||
var arena = std.heap.ArenaAllocator.init(testing.allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
const request_json = try std.json.stringifyAlloc(std.testing.allocator, request, .{});
|
||||
const request_json = try std.fmt.allocPrint(std.testing.allocator, "{f}", .{std.json.fmt(request, .{})});
|
||||
defer std.testing.allocator.free(request_json);
|
||||
|
||||
const parsed = try std.json.parseFromSlice(struct {
|
||||
|
@ -2699,7 +2699,7 @@ test "jsonStringify: strings" {
|
|||
var arena = std.heap.ArenaAllocator.init(testing.allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
const request_json = try std.json.stringifyAlloc(std.testing.allocator, request, .{});
|
||||
const request_json = try std.fmt.allocPrint(std.testing.allocator, "{f}", .{std.json.fmt(request, .{})});
|
||||
defer std.testing.allocator.free(request_json);
|
||||
|
||||
try testing.expectEqualStrings("{\"arn\":\"1234\"}", request_json);
|
||||
|
@ -2721,7 +2721,7 @@ test "jsonStringify" {
|
|||
var arena = std.heap.ArenaAllocator.init(testing.allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
const request_json = try std.json.stringifyAlloc(std.testing.allocator, request, .{});
|
||||
const request_json = try std.fmt.allocPrint(std.testing.allocator, "{f}", .{std.json.fmt(request, .{})});
|
||||
defer std.testing.allocator.free(request_json);
|
||||
|
||||
const json_parsed = try std.json.parseFromSlice(struct {
|
||||
|
@ -2748,7 +2748,7 @@ test "jsonStringify nullable object" {
|
|||
},
|
||||
};
|
||||
|
||||
const request_json = try std.json.stringifyAlloc(std.testing.allocator, request, .{});
|
||||
const request_json = try std.fmt.allocPrint(std.testing.allocator, "{f}", .{std.json.fmt(request, .{})});
|
||||
defer std.testing.allocator.free(request_json);
|
||||
|
||||
const json_parsed = try std.json.parseFromSlice(struct {
|
||||
|
@ -2774,7 +2774,7 @@ test "jsonStringify nullable object" {
|
|||
.ciphertext_blob = "bar",
|
||||
};
|
||||
|
||||
const request_json = try std.json.stringifyAlloc(std.testing.allocator, request, .{});
|
||||
const request_json = try std.fmt.allocPrint(std.testing.allocator, "{f}", .{std.json.fmt(request, .{})});
|
||||
defer std.testing.allocator.free(request_json);
|
||||
|
||||
const json_parsed = try std.json.parseFromSlice(struct {
|
||||
|
|
|
@ -348,10 +348,10 @@ pub fn freeSignedRequest(allocator: std.mem.Allocator, request: *base.Request, c
|
|||
|
||||
pub const credentialsFn = *const fn ([]const u8) ?Credentials;
|
||||
|
||||
pub fn verifyServerRequest(allocator: std.mem.Allocator, request: *std.http.Server.Request, request_body_reader: anytype, credentials_fn: credentialsFn) !bool {
|
||||
pub fn verifyServerRequest(allocator: std.mem.Allocator, request: *std.http.Server.Request, credentials_fn: credentialsFn) !bool {
|
||||
var unverified_request = try UnverifiedRequest.init(allocator, request);
|
||||
defer unverified_request.deinit();
|
||||
return verify(allocator, unverified_request, request_body_reader, credentials_fn);
|
||||
return verify(allocator, unverified_request, credentials_fn);
|
||||
}
|
||||
|
||||
pub const UnverifiedRequest = struct {
|
||||
|
@ -359,17 +359,19 @@ pub const UnverifiedRequest = struct {
|
|||
target: []const u8,
|
||||
method: std.http.Method,
|
||||
allocator: std.mem.Allocator,
|
||||
raw: *std.http.Server.Request,
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator, request: *std.http.Server.Request) !UnverifiedRequest {
|
||||
var al = std.ArrayList(std.http.Header).init(allocator);
|
||||
defer al.deinit();
|
||||
var al = std.ArrayList(std.http.Header){};
|
||||
defer al.deinit(allocator);
|
||||
var it = request.iterateHeaders();
|
||||
while (it.next()) |h| try al.append(h);
|
||||
while (it.next()) |h| try al.append(allocator, h);
|
||||
return .{
|
||||
.target = request.head.target,
|
||||
.method = request.head.method,
|
||||
.headers = try al.toOwnedSlice(),
|
||||
.headers = try al.toOwnedSlice(allocator),
|
||||
.allocator = allocator,
|
||||
.raw = request,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -387,7 +389,7 @@ pub const UnverifiedRequest = struct {
|
|||
}
|
||||
};
|
||||
|
||||
pub fn verify(allocator: std.mem.Allocator, request: UnverifiedRequest, request_body_reader: anytype, credentials_fn: credentialsFn) !bool {
|
||||
pub fn verify(allocator: std.mem.Allocator, request: UnverifiedRequest, credentials_fn: credentialsFn) !bool {
|
||||
var arena = std.heap.ArenaAllocator.init(allocator);
|
||||
defer arena.deinit();
|
||||
const aa = arena.allocator();
|
||||
|
@ -420,7 +422,6 @@ pub fn verify(allocator: std.mem.Allocator, request: UnverifiedRequest, request_
|
|||
return verifyParsedAuthorization(
|
||||
aa,
|
||||
request,
|
||||
request_body_reader,
|
||||
credential.?,
|
||||
signed_headers.?,
|
||||
signature.?,
|
||||
|
@ -431,7 +432,6 @@ pub fn verify(allocator: std.mem.Allocator, request: UnverifiedRequest, request_
|
|||
fn verifyParsedAuthorization(
|
||||
allocator: std.mem.Allocator,
|
||||
request: UnverifiedRequest,
|
||||
request_body_reader: anytype,
|
||||
credential: []const u8,
|
||||
signed_headers: []const u8,
|
||||
signature: []const u8,
|
||||
|
@ -494,7 +494,8 @@ fn verifyParsedAuthorization(
|
|||
.content_type = request.getFirstHeaderValue("content-type").?,
|
||||
};
|
||||
signed_request.query = request.target[signed_request.path.len..]; // TODO: should this be +1? query here would include '?'
|
||||
signed_request.body = try request_body_reader.readAllAlloc(allocator, std.math.maxInt(usize));
|
||||
// TODO: This is almost certainly not what we want here long term, but will get tests working
|
||||
signed_request.body = try request.raw.server.reader.in.allocRemaining(allocator, .unlimited);
|
||||
defer allocator.free(signed_request.body);
|
||||
signed_request = try signRequest(allocator, signed_request, config);
|
||||
defer freeSignedRequest(allocator, &signed_request, config);
|
||||
|
@ -1010,13 +1011,13 @@ test "canonical query" {
|
|||
test "canonical headers" {
|
||||
const allocator = std.testing.allocator;
|
||||
var headers = try std.ArrayList(std.http.Header).initCapacity(allocator, 5);
|
||||
defer headers.deinit();
|
||||
try headers.append(.{ .name = "Host", .value = "iam.amazonaws.com" });
|
||||
try headers.append(.{ .name = "Content-Type", .value = "application/x-www-form-urlencoded; charset=utf-8" });
|
||||
try headers.append(.{ .name = "User-Agent", .value = "This header should be skipped" });
|
||||
try headers.append(.{ .name = "My-header1", .value = " a b c " });
|
||||
try headers.append(.{ .name = "X-Amz-Date", .value = "20150830T123600Z" });
|
||||
try headers.append(.{ .name = "My-header2", .value = " \"a b c\" " });
|
||||
defer headers.deinit(allocator);
|
||||
try headers.append(allocator, .{ .name = "Host", .value = "iam.amazonaws.com" });
|
||||
try headers.append(allocator, .{ .name = "Content-Type", .value = "application/x-www-form-urlencoded; charset=utf-8" });
|
||||
try headers.append(allocator, .{ .name = "User-Agent", .value = "This header should be skipped" });
|
||||
try headers.append(allocator, .{ .name = "My-header1", .value = " a b c " });
|
||||
try headers.append(allocator, .{ .name = "X-Amz-Date", .value = "20150830T123600Z" });
|
||||
try headers.append(allocator, .{ .name = "My-header2", .value = " \"a b c\" " });
|
||||
const expected =
|
||||
\\content-type:application/x-www-form-urlencoded; charset=utf-8
|
||||
\\host:iam.amazonaws.com
|
||||
|
@ -1035,12 +1036,12 @@ test "canonical headers" {
|
|||
test "canonical request" {
|
||||
const allocator = std.testing.allocator;
|
||||
var headers = try std.ArrayList(std.http.Header).initCapacity(allocator, 5);
|
||||
defer headers.deinit();
|
||||
try headers.append(.{ .name = "User-agent", .value = "c sdk v1.0" });
|
||||
defer headers.deinit(allocator);
|
||||
try headers.append(allocator, .{ .name = "User-agent", .value = "c sdk v1.0" });
|
||||
// In contrast to AWS CRT (aws-c-auth), we add the date as part of the
|
||||
// signing operation. They add it as part of the canonicalization
|
||||
try headers.append(.{ .name = "X-Amz-Date", .value = "20150830T123600Z" });
|
||||
try headers.append(.{ .name = "Host", .value = "example.amazonaws.com" });
|
||||
try headers.append(allocator, .{ .name = "X-Amz-Date", .value = "20150830T123600Z" });
|
||||
try headers.append(allocator, .{ .name = "Host", .value = "example.amazonaws.com" });
|
||||
const req = base.Request{
|
||||
.path = "/",
|
||||
.method = "GET",
|
||||
|
@ -1095,10 +1096,10 @@ test "can sign" {
|
|||
|
||||
const allocator = std.testing.allocator;
|
||||
var headers = try std.ArrayList(std.http.Header).initCapacity(allocator, 5);
|
||||
defer headers.deinit();
|
||||
try headers.append(.{ .name = "Content-Type", .value = "application/x-www-form-urlencoded; charset=utf-8" });
|
||||
try headers.append(.{ .name = "Content-Length", .value = "13" });
|
||||
try headers.append(.{ .name = "Host", .value = "example.amazonaws.com" });
|
||||
defer headers.deinit(allocator);
|
||||
try headers.append(allocator, .{ .name = "Content-Type", .value = "application/x-www-form-urlencoded; charset=utf-8" });
|
||||
try headers.append(allocator, .{ .name = "Content-Length", .value = "13" });
|
||||
try headers.append(allocator, .{ .name = "Host", .value = "example.amazonaws.com" });
|
||||
const req = base.Request{
|
||||
.path = "/",
|
||||
.query = "",
|
||||
|
@ -1165,25 +1166,25 @@ test "can verify server request" {
|
|||
"X-Amz-Date: 20230908T170252Z\r\n" ++
|
||||
"x-amz-content-sha256: fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9\r\n" ++
|
||||
"Authorization: AWS4-HMAC-SHA256 Credential=ACCESS/20230908/us-west-2/s3/aws4_request, SignedHeaders=accept;content-length;content-type;host;x-amz-content-sha256;x-amz-date;x-amz-storage-class, Signature=fcc43ce73a34c9bd1ddf17e8a435f46a859812822f944f9eeb2aabcd64b03523\r\n\r\nbar";
|
||||
var read_buffer: [1024]u8 = undefined;
|
||||
@memcpy(read_buffer[0..req.len], req);
|
||||
var reader = std.Io.Reader.fixed(req);
|
||||
var server: std.http.Server = .{
|
||||
.connection = undefined,
|
||||
.out = undefined, // We're not sending a response here
|
||||
.reader = .{
|
||||
.in = &reader,
|
||||
.interface = undefined,
|
||||
.state = .ready,
|
||||
.read_buffer = &read_buffer,
|
||||
.read_buffer_len = req.len,
|
||||
.next_request_start = 0,
|
||||
.max_head_len = req.len,
|
||||
},
|
||||
};
|
||||
var request: std.http.Server.Request = .{
|
||||
.server = &server,
|
||||
.head_end = req.len - 3,
|
||||
.head = try std.http.Server.Request.Head.parse(read_buffer[0 .. req.len - 3]),
|
||||
.reader_state = undefined,
|
||||
.head = undefined,
|
||||
.head_buffer = &.{},
|
||||
};
|
||||
// I think we need a request.receiveHead() call here
|
||||
|
||||
// std.testing.log_level = .debug;
|
||||
var fbs = std.io.fixedBufferStream("bar");
|
||||
try std.testing.expect(try verifyServerRequest(allocator, &request, fbs.reader(), struct {
|
||||
try std.testing.expect(try verifyServerRequest(allocator, &request, struct {
|
||||
cred: Credentials,
|
||||
|
||||
const Self = @This();
|
||||
|
@ -1221,22 +1222,24 @@ test "can verify server request without x-amz-content-sha256" {
|
|||
const req_data = head ++ body;
|
||||
var read_buffer: [2048]u8 = undefined;
|
||||
@memcpy(read_buffer[0..req_data.len], req_data);
|
||||
var reader = std.Io.Reader.fixed(&read_buffer);
|
||||
var server: std.http.Server = .{
|
||||
.connection = undefined,
|
||||
.out = undefined, // We're not sending a response here
|
||||
.reader = .{
|
||||
.interface = undefined,
|
||||
.in = &reader,
|
||||
.state = .ready,
|
||||
.read_buffer = &read_buffer,
|
||||
.read_buffer_len = req_data.len,
|
||||
.next_request_start = 0,
|
||||
.max_head_len = 1024,
|
||||
},
|
||||
};
|
||||
var request: std.http.Server.Request = .{
|
||||
.server = &server,
|
||||
.head_end = head.len,
|
||||
.head = try std.http.Server.Request.Head.parse(read_buffer[0..head.len]),
|
||||
.reader_state = undefined,
|
||||
.head = undefined,
|
||||
.head_buffer = &.{},
|
||||
};
|
||||
{
|
||||
var h = std.ArrayList(std.http.Header).init(allocator);
|
||||
defer h.deinit();
|
||||
var h = try std.ArrayList(std.http.Header).initCapacity(allocator, 4);
|
||||
defer h.deinit(allocator);
|
||||
const signed_headers = &[_][]const u8{ "content-type", "host", "x-amz-date", "x-amz-target" };
|
||||
var it = request.iterateHeaders();
|
||||
while (it.next()) |source| {
|
||||
|
@ -1245,7 +1248,7 @@ test "can verify server request without x-amz-content-sha256" {
|
|||
match = std.ascii.eqlIgnoreCase(s, source.name);
|
||||
if (match) break;
|
||||
}
|
||||
if (match) try h.append(.{ .name = source.name, .value = source.value });
|
||||
if (match) try h.append(allocator, .{ .name = source.name, .value = source.value });
|
||||
}
|
||||
const req = base.Request{
|
||||
.path = "/",
|
||||
|
@ -1282,9 +1285,7 @@ test "can verify server request without x-amz-content-sha256" {
|
|||
}
|
||||
|
||||
{ // verification
|
||||
var fis = std.io.fixedBufferStream(body[0..]);
|
||||
|
||||
try std.testing.expect(try verifyServerRequest(allocator, &request, fis.reader(), struct {
|
||||
try std.testing.expect(try verifyServerRequest(allocator, &request, struct {
|
||||
cred: Credentials,
|
||||
|
||||
const Self = @This();
|
||||
|
|
44
src/url.zig
44
src/url.zig
|
@ -103,8 +103,7 @@ pub fn encodeInternal(
|
|||
return rc;
|
||||
}
|
||||
|
||||
fn testencode(allocator: std.mem.Allocator, expected: []const u8, value: anytype, comptime options: EncodingOptions) !void {
|
||||
const ValidationWriter = struct {
|
||||
const ValidationWriter = struct {
|
||||
const Self = @This();
|
||||
pub const Writer = std.io.Writer(*Self, Error, write);
|
||||
pub const Error = error{
|
||||
|
@ -113,17 +112,30 @@ fn testencode(allocator: std.mem.Allocator, expected: []const u8, value: anytype
|
|||
};
|
||||
|
||||
expected_remaining: []const u8,
|
||||
writer: std.Io.Writer,
|
||||
|
||||
fn init(exp: []const u8) Self {
|
||||
return .{ .expected_remaining = exp };
|
||||
return .{
|
||||
.expected_remaining = exp,
|
||||
.writer = .{
|
||||
.buffer = &.{},
|
||||
.vtable = &.{
|
||||
.drain = drain,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn writer(self: *Self) Writer {
|
||||
return .{ .context = self };
|
||||
fn drain(w: *std.Io.Writer, data: []const []const u8, splat: usize) std.Io.Writer.Error!usize {
|
||||
if (splat > 0) @panic("No splat");
|
||||
const self: *ValidationWriter = @fieldParentPtr("writer", w);
|
||||
|
||||
var bytes: usize = 0;
|
||||
for (data) |d| bytes += try self.write(d);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
fn write(self: *Self, bytes: []const u8) Error!usize {
|
||||
// std.debug.print("{s}\n", .{bytes});
|
||||
fn write(self: *Self, bytes: []const u8) std.Io.Writer.Error!usize {
|
||||
if (self.expected_remaining.len < bytes.len) {
|
||||
std.log.warn(
|
||||
\\====== expected this output: =========
|
||||
|
@ -135,7 +147,7 @@ fn testencode(allocator: std.mem.Allocator, expected: []const u8, value: anytype
|
|||
self.expected_remaining,
|
||||
bytes,
|
||||
});
|
||||
return error.TooMuchData;
|
||||
return error.WriteFailed;
|
||||
}
|
||||
if (!std.mem.eql(u8, self.expected_remaining[0..bytes.len], bytes)) {
|
||||
std.log.warn(
|
||||
|
@ -148,15 +160,15 @@ fn testencode(allocator: std.mem.Allocator, expected: []const u8, value: anytype
|
|||
self.expected_remaining[0..bytes.len],
|
||||
bytes,
|
||||
});
|
||||
return error.DifferentData;
|
||||
return error.WriteFailed;
|
||||
}
|
||||
self.expected_remaining = self.expected_remaining[bytes.len..];
|
||||
return bytes.len;
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
fn testencode(allocator: std.mem.Allocator, expected: []const u8, value: anytype, comptime options: EncodingOptions) !void {
|
||||
var vos = ValidationWriter.init(expected);
|
||||
try encode(allocator, value, vos.writer(), options);
|
||||
try encode(allocator, value, &vos.writer, options);
|
||||
if (vos.expected_remaining.len > 0) return error.NotEnoughData;
|
||||
}
|
||||
|
||||
|
@ -238,17 +250,17 @@ test "can urlencode an EC2 Filter" {
|
|||
},
|
||||
.{},
|
||||
) catch |err| {
|
||||
var al = std.ArrayList(u8).init(std.testing.allocator);
|
||||
defer al.deinit();
|
||||
var aw = std.Io.Writer.Allocating.init(std.testing.allocator);
|
||||
defer aw.deinit();
|
||||
try encode(
|
||||
std.testing.allocator,
|
||||
Request{
|
||||
.filters = @constCast(&[_]Filter{.{ .name = "foo", .values = @constCast(&[_][]const u8{"bar"}) }}),
|
||||
},
|
||||
al.writer(),
|
||||
&aw.writer,
|
||||
.{},
|
||||
);
|
||||
std.log.warn("Error found. Full encoding is '{s}'", .{al.items});
|
||||
std.log.warn("Error found. Full encoding is '{s}'", .{aw.written()});
|
||||
return err;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue