From 797fdaa4d40a4f22f2c99aa22061f6d70ea61170 Mon Sep 17 00:00:00 2001 From: Edoardo Vacchi Date: Wed, 19 Feb 2025 16:36:39 +0100 Subject: [PATCH 1/2] feat: support `required` fields (make the others optional) Signed-off-by: Edoardo Vacchi --- src/index.ts | 7 ++++++- template/src/schema.zig.ejs | 14 +++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/index.ts b/src/index.ts index 9c51b8c..63f95dc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ import ejs from "ejs"; -import { getContext, helpers, Property, XtpSchema } from "@dylibso/xtp-bindgen"; +import { getContext, helpers, Property, XtpSchema, Schema } from "@dylibso/xtp-bindgen"; function toZigType(property: Property, pkg?: string): string { if (property.$ref) { @@ -41,6 +41,10 @@ function pointerToZigType(property: Property) { return `*${typ}`; } +function isZigOptional(schema: Schema, property: Property) { + return property.nullable || !schema.required?.includes(property.name); +} + function addStdImport(schema: XtpSchema) { // in the generated `main.zig` this would include a reference to // std.json.ArrayHashMap and std.json.Value, so we import "std". @@ -77,6 +81,7 @@ export function render() { const ctx = { ...helpers, ...getContext(), + isZigOptional, toZigType, pointerToZigType, addStdImport, diff --git a/template/src/schema.zig.ejs b/template/src/schema.zig.ejs index edcb20c..71344e1 100644 --- a/template/src/schema.zig.ejs +++ b/template/src/schema.zig.ejs @@ -95,7 +95,7 @@ pub const Host = struct { <% if (p.description) { -%> /// <%- formatCommentBlock(p.description, "/// ") %> <% } -%> - <%- p.name %>: <%- p.nullable ? "?" : null %><%- toZigType(p) %><%- p.nullable ? " = null" : null %>, + <%- p.name %>: <%- isZigOptional(schema, p) ? "?" : null %><%- toZigType(p) %><%- isZigOptional(schema, p) ? " = null" : null %>, <% }) %> /// Internally used function, should not be called by plugin authors. @@ -105,11 +105,11 @@ pub const Host = struct { <% } %> <% schema.properties.forEach(p => { -%> <% if (p.$ref && !p.$ref.enum) { %> - <% if (p.nullable) { %> + <% if (isZigOptional(schema, p)) { %> if (self.<%- p.name %> != null) { <% } -%> - self.<%- p.name %> = (try self.<%- p.name %>.<%- p.nullable ? '?.' : null %>XXX__decodeBase64Fields()).*; - <% if (p.nullable) { %> + self.<%- p.name %> = (try self.<%- p.name %>.<%- isZigOptional(schema, p) ? '?.' : null %>XXX__decodeBase64Fields()).*; + <% if (isZigOptional(schema, p)) { %> } <% } -%> <% } else if (p.type === 'buffer') { %> @@ -129,11 +129,11 @@ pub const Host = struct { <% } %> <% schema.properties.forEach(p => { -%> <% if (p.$ref && !p.$ref.enum) { %> - <% if (p.nullable) { %> + <% if (isZigOptional(schema, p)) { %> if (self.<%- p.name %> != null) { <% } -%> - self.<%- p.name %> = (try self.<%- p.name %>.<%- p.nullable ? '?.' : null %>XXX__encodeBase64Fields()).*; - <% if (p.nullable) { %> + self.<%- p.name %> = (try self.<%- p.name %>.<%- isZigOptional(schema, p) ? '?.' : null %>XXX__encodeBase64Fields()).*; + <% if (isZigOptional(schema, p)) { %> } <% } -%> <% } else if (p.type === 'buffer') { %> From 4418c74881a39f8e3dafab6fb7af3c1d85d292b2 Mon Sep 17 00:00:00 2001 From: Edoardo Vacchi Date: Wed, 19 Feb 2025 17:40:14 +0100 Subject: [PATCH 2/2] handle nullable buffers Signed-off-by: Edoardo Vacchi --- template/src/schema.zig.ejs | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/template/src/schema.zig.ejs b/template/src/schema.zig.ejs index 71344e1..dfba842 100644 --- a/template/src/schema.zig.ejs +++ b/template/src/schema.zig.ejs @@ -113,10 +113,20 @@ pub const Host = struct { } <% } -%> <% } 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 %>; - <% } %> + <% if (isZigOptional(schema, p)) { %> + if (self.aBuffer != null) { + <% } /* end isZigOptional */ -%> + + const srcBuf = self.<%- p.name %><%- isZigOptional(schema, p) ? '.?' : null %>; + const dest_<%- p.name %> = try std.heap.wasm_allocator.alloc(u8, try b64dec.calcSizeForSlice(srcBuf)); + try b64dec.decode(dest_<%- p.name %>, srcBuf); + self.<%- p.name %> = dest_<%- p.name %>; + + <% if (isZigOptional(schema, p)) { %> + } + <% } /* end isZigOptional */ -%> + + <% } /* end buffer */ %> <% }) %> return self; @@ -137,8 +147,15 @@ pub const Host = struct { } <% } -%> <% } 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 %>); + <% if (isZigOptional(schema, p)) { %> + if (self.<%- p.name %> != null) { + <% } -%> + const srcBuf = self.<%- p.name %><%- isZigOptional(schema, p) ? '.?' : null %>; + const dest_<%- p.name %> = try std.heap.wasm_allocator.alloc(u8, b64enc.calcSize(srcBuf.len)); + self.<%- p.name %> = b64enc.encode(dest_<%- p.name %>, srcBuf); + <% if (isZigOptional(schema, p)) { %> + } + <% } /* end isZigOptional */ -%> <% } %> <% }) %>