Skip to content

Commit

Permalink
feat: convert buffers to base64 for json contentType
Browse files Browse the repository at this point in the history
  • Loading branch information
nilslice committed Sep 11, 2024
1 parent e106bf5 commit cbd566c
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 37 deletions.
109 changes: 82 additions & 27 deletions template/src/pdk.zig.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,67 @@ export fn <%- ex.name %>() i32 {
<% if (ex.input.contentType === 'application/json') { -%>
// in JSON
<% if (ex.input.$ref) { -%>
const json_input = _plugin.getJsonOpt(schema.<%- ex.input.$ref.name %>, .{}) catch |err| {
const json_input = _plugin.getJsonOpt(schema.<%- zigTypeName(ex.input.$ref.name) %>, .{}) catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
};
defer json_input.deinit();
const input = json_input.value();
var input = json_input.value();
// decode all the inner buffer fields from base64 (may be no-op)
input = (input.__decodeBase64Fields() catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
}).*;
<% } else if (ex.input.type === 'buffer') { -%>
var input = json_input.value();
var b64dec = std.base64.standard_no_pad.Decoder;
const n = b64dec.calcSizeForSlice(input) catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
};
const dest = _plugin.allocator.alloc(u8, n) catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
};
b64dec.decode(dest, input) catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
};
input = dest;
<% } else if (ex.input.type === 'object') { -%>
const s = _plugin.getInput() catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
};
defer _plugin.allocator.free(s);
const parsed_input = std.json.parseFromSlice(std.json.ArrayHashMap(std.json.Value), _plugin.allocator, s, .{ .allocate = .alloc_always }) catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
};
const input = parsed_input.value;
const s = _plugin.getInput() catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
};
defer _plugin.allocator.free(s);
const parsed_input = std.json.parseFromSlice(std.json.ArrayHashMap(std.json.Value), _plugin.allocator, s, .{ .allocate = .alloc_always }) catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
};
const input = parsed_input.value;
<% } else { -%>
const s = _plugin.getInput() catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
};
defer _plugin.allocator.free(s);
const parsed_input = std.json.parseFromSlice(<%- toZigType(ex.input) %>, _plugin.allocator, s, .{ .allocate = .alloc_always }) catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
};
const input = parsed_input.value;
const s = _plugin.getInput() catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
};
defer _plugin.allocator.free(s);
const parsed_input = std.json.parseFromSlice(<%- toZigType(ex.input) %>, _plugin.allocator, s, .{ .allocate = .alloc_always }) catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
};
const input = parsed_input.value;
<% } -%>
<% } else if (ex.input.type === 'string') { -%>
Expand Down Expand Up @@ -108,7 +136,34 @@ export fn <%- ex.name %>() i32 {
<% if (ex.output) { -%>
<% if (ex.output.contentType === 'application/json') { -%>
_plugin.outputJson(output, .{}) catch |err| {
var json_output = output;
<% if (ex.output.$ref) { -%>
// encode all the inner buffer fields to base64 (may be no-op)
json_output = (json_output.__encodeBase64Fields() catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
}).*;
<% } else if (ex.output.type === 'buffer') { -%>
var b64enc = std.base64.standard_no_pad.Encoder;
const out_n = b64enc.calcSize(json_output.len) catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
};
const out_dest = _plugin.allocator.alloc(u8, out_n) catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
};
b64enc.encode(out_dest, json_output) catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
};
json_output = out_dest;
<% } -%>
_plugin.outputJson(json_output, .{}) catch |err| {
const msg = std.fmt.allocPrint(_plugin.allocator, "{}", .{err}) catch ERR_PRINTING_MSG;
_plugin.setError(msg);
return -1;
Expand Down
53 changes: 43 additions & 10 deletions template/src/schema.zig.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,48 @@ pub const Host = struct {
<% } -%>
<%- p.name %>: <%- p.nullable ? "?" : null %><%- toZigType(p) %>,
<% }) %>
pub fn __decodeBase64Fields(self: *<%- zigTypeName(schema.name) %>) !*<%- zigTypeName(schema.name) %> {
<% if (schema.properties.some(p => { return p.type === 'buffer' })) { -%>
var b64dec = std.base64.standard_no_pad.Decoder;
<% } %>
<% schema.properties.forEach(p => { -%>
<% if (p.$ref && !p.$ref.enum) { %>
self.<%- p.name %> = (try self.<%- p.name %>.__decodeBase64Fields()).*;
<% } else if (p.type === 'buffer') { %>
const dest_<%- p.name %> = try std.heap.wasm_allocator.alloc(u8, try b64dec.calcSizeForSlice(self.<%- p.name %>));
try b64dec.decode(dest_<%- p.name %>, self.<%- p.name %>);
self.<%- p.name %> = dest_<%- p.name %>;
<% } %>
<% }) %>
return self;
}
pub fn __encodeBase64Fields(self: *<%- zigTypeName(schema.name) %>) !*<%- zigTypeName(schema.name) %> {
<% if (schema.properties.some(p => { return p.type === 'buffer' })) { -%>
var b64enc = std.base64.standard.Encoder;
<% } %>
<% schema.properties.forEach(p => { -%>
<% if (p.$ref && !p.$ref.enum) { %>
self.<%- p.name %> = (try self.<%- p.name %>.__encodeBase64Fields()).*;
<% } else if (p.type === 'buffer') { %>
const dest_<%- p.name %> = try std.heap.wasm_allocator.alloc(u8, b64enc.calcSize(self.<%- p.name %>.len));
self.<%- p.name %> = b64enc.encode(dest_<%- p.name %>, self.<%- p.name %>);
<% } %>
<% }) %>
return self;
}
};
<% } else if (schema.enum) { %>
<% if (schema.description) { -%>
/// <%- formatCommentBlock(schema.description, "/// ") %>
<% } -%>
pub const <%- zigTypeName(schema.name) %> = enum {
<% schema.enum.forEach((variant) => { -%>
<%- variant %>,
<% }) -%>
};
<% } -%>
<% } else if (schema.enum) { %>
<% if (schema.description) { -%>
/// <%- formatCommentBlock(schema.description, "/// ") %>
<% } -%>
pub const <%- zigTypeName(schema.name) %> = enum {
<% schema.enum.forEach((variant) => { -%>
<%- variant %>,
<% }) -%>
};
<% } -%>
<% }) %>

0 comments on commit cbd566c

Please sign in to comment.