diff --git a/build.zig b/build.zig index 49799f0..c25cd2e 100644 --- a/build.zig +++ b/build.zig @@ -33,6 +33,7 @@ pub fn build(b: *std.build.Builder) !void { .{ .name = "hello_json", .src = "examples/hello_json/hello_json.zig" }, .{ .name = "endpoint", .src = "examples/endpoint/main.zig" }, .{ .name = "wrk", .src = "wrk/zig/main.zig" }, + .{ .name = "mustache", .src = "examples/mustache/mustache.zig" }, }) |excfg| { const ex_name = excfg.name; const ex_src = excfg.src; diff --git a/src/mustache.zig b/src/mustache.zig index ac8cef8..76bdd82 100644 --- a/src/mustache.zig +++ b/src/mustache.zig @@ -2,22 +2,33 @@ // (see http://facil.io/0.7.x/fiobj_mustache) // easier / possible / more zig-like -const C = @cImport({ - @cInclude("mustache_parser.h"); - @cInclude("fiobj_mustache.h"); -}); +// const C = @cImport({ +// @cInclude("mustache_parser.h"); +// @cInclude("fiobj_mustache.h"); +// }); + +const util = @import("util.zig"); + +pub const FIOBJ = usize; +pub const struct_mustache_s = opaque {}; +pub const enum_mustache_error_en = c_uint; +pub const mustache_error_en = enum_mustache_error_en; + +pub const mustache_s = struct_mustache_s; +pub extern fn fiobj_mustache_new(args: MustacheLoadArgs) ?*mustache_s; +pub extern fn fiobj_mustache_build(mustache: ?*mustache_s, data: FIOBJ) FIOBJ; +pub extern fn fiobj_mustache_build2(dest: FIOBJ, mustache: ?*mustache_s, data: FIOBJ) FIOBJ; +pub extern fn fiobj_mustache_free(mustache: ?*mustache_s) void; pub const MustacheLoadArgs = extern struct { filename: [*c]const u8, filename_len: usize, data: [*c]const u8, data_len: usize, - err: [*c]C.mustache_error_en, + err: [*c]mustache_error_en, }; -// pub const struct_mustache_s = opaque {}; -// pub const mustache_s = struct_mustache_s; -pub const Mustache = C.mustache_s; +pub const Mustache = mustache_s; pub const MustacheStatus = enum(c_int) {}; @@ -44,17 +55,18 @@ pub const MustacheError = error{ // pub extern fn fiobj_mustache_build2(dest: FIOBJ, mustache: ?*mustache_s, data: FIOBJ) FIOBJ; pub fn MustacheNew(data: []const u8) MustacheError!*Mustache { - var err: C.mustache_error_en = undefined; + // pub fn MustacheNew(data: []const u8) !*Mustache { + var err: mustache_error_en = undefined; var args: MustacheLoadArgs = .{ .filename = null, .filename_len = 0, - .data = data, + .data = data.ptr, .data_len = data.len, .err = &err, }; - var ret = C.fiobj_mustache_new(args); + var ret = fiobj_mustache_new(args); switch (err) { - 0 => return ret, + 0 => return ret.?, 1 => return MustacheError.MUSTACHE_ERR_TOO_DEEP, 2 => return MustacheError.MUSTACHE_ERR_CLOSURE_MISMATCH, 3 => return MustacheError.MUSTACHE_ERR_FILE_NOT_FOUND, @@ -66,11 +78,55 @@ pub fn MustacheNew(data: []const u8) MustacheError!*Mustache { 9 => return MustacheError.MUSTACHE_ERR_NAME_TOO_LONG, 10 => return MustacheError.MUSTACHE_ERR_UNKNOWN, 11 => return MustacheError.MUSTACHE_ERR_USER_ERROR, - else => MustacheError.MustacheError.MUSTACHE_ERR_UNKNOWN, + else => return MustacheError.MUSTACHE_ERR_UNKNOWN, } } -test "MustacheNew" { - const template = "{{=<< >>=}}* Users:\r\n<<#users>><>. <<& name>> (<>)\r\n<>\r\nNested: <<& nested.item >>."; - _ = MustacheNew(template); +// implement these: fiobj_mustache.c +// pub extern fn fiobj_mustache_build(mustache: ?*mustache_s, data: FIOBJ) FIOBJ; +// pub extern fn fiobj_mustache_build2(dest: FIOBJ, mustache: ?*mustache_s, data: FIOBJ) FIOBJ; + +pub extern fn fiobj_hash_new() FIOBJ; + +// this build is slow because it needs to translate to a FIOBJ data +// object FIOBJ_T_HASH +pub fn MustacheBuild(mustache: *Mustache, data: ?FIOBJ) ?[]const u8 { + _ = data; + + // FIOBJ data = fiobj_hash_new(); + // FIOBJ key = fiobj_str_new("users", 5); + // FIOBJ ary = fiobj_ary_new2(4); + // fiobj_hash_set(data, key, ary); + // fiobj_free(key); + // for (int i = 0; i < 4; ++i) { + // FIOBJ id = fiobj_str_buf(4); + // fiobj_str_write_i(id, i); + // FIOBJ name = fiobj_str_buf(4); + // fiobj_str_write(name, "User ", 5); + // fiobj_str_write_i(name, i); + // FIOBJ usr = fiobj_hash_new2(2); + // key = fiobj_str_new("id", 2); + // fiobj_hash_set(usr, key, id); + // fiobj_free(key); + // key = fiobj_str_new("name", 4); + // fiobj_hash_set(usr, key, name); + // fiobj_free(key); + // fiobj_ary_push(ary, usr); + // } + // key = fiobj_str_new("nested", 6); + // ary = fiobj_hash_new2(2); + // fiobj_hash_set(data, key, ary); + // fiobj_free(key); + // key = fiobj_str_new("item", 4); + // fiobj_hash_set(ary, key, fiobj_str_new("dot notation success", 20)); + // fiobj_free(key); + + var empty = fiobj_hash_new(); + var ret = fiobj_mustache_build(mustache, empty); + return util.fio2str(ret); +} + +// pub extern fn fiobj_mustache_free(mustache: ?*mustache_s) void; +pub fn MustacheFree(m: ?*Mustache) void { + fiobj_mustache_free(m); } diff --git a/src/util.zig b/src/util.zig index bc739fb..fae4c8d 100644 --- a/src/util.zig +++ b/src/util.zig @@ -1,5 +1,28 @@ const std = @import("std"); +pub const C = @cImport({ + @cInclude("http.h"); + @cInclude("fio.h"); +}); + +pub fn fio2str(o: C.FIOBJ) ?[]const u8 { + if (o == 0) return null; + const x: C.fio_str_info_s = C.fiobj_obj2cstr(o); + return std.mem.span(x.data); +} + +pub fn str2fio(s: []const u8) C.fio_str_info_s { + return .{ + .data = toCharPtr(s), + .len = s.len, + .capa = s.len, + }; +} + +fn toCharPtr(s: []const u8) [*c]u8 { + return @intToPtr([*c]u8, @ptrToInt(s.ptr)); +} + // // JSON helpers // diff --git a/src/zap.zig b/src/zap.zig index 99bd92b..3b0cc72 100644 --- a/src/zap.zig +++ b/src/zap.zig @@ -12,26 +12,10 @@ pub usingnamespace @import("util.zig"); pub usingnamespace @import("http.zig"); pub usingnamespace @import("mustache.zig"); +const util = @import("util.zig"); + const _module = @This(); -pub fn fio2str(o: C.FIOBJ) ?[]const u8 { - if (o == 0) return null; - const x: C.fio_str_info_s = C.fiobj_obj2cstr(o); - return std.mem.span(x.data); -} - -pub fn str2fio(s: []const u8) C.fio_str_info_s { - return .{ - .data = toCharPtr(s), - .len = s.len, - .capa = s.len, - }; -} - -fn toCharPtr(s: []const u8) [*c]u8 { - return @intToPtr([*c]u8, @ptrToInt(s.ptr)); -} - pub fn start(args: C.fio_start_args) void { C.fio_start(args); } @@ -94,12 +78,12 @@ pub const SimpleRequest = struct { pub fn setHeader(self: *const Self, name: []const u8, value: []const u8) void { const hname: C.fio_str_info_s = .{ - .data = toCharPtr(name), + .data = util.toCharPtr(name), .len = name.len, .capa = name.len, }; const vname: C.fio_str_info_s = .{ - .data = toCharPtr(value), + .data = util.toCharPtr(value), .len = value.len, .capa = value.len, }; @@ -126,8 +110,8 @@ pub const SimpleRequest = struct { return null; } return HttpParam{ - .key = fio2str(key).?, - .value = fio2str(value).?, + .key = util.fio2str(key).?, + .value = util.fio2str(value).?, }; } }; @@ -162,10 +146,10 @@ pub const SimpleHttpListener = struct { pub fn theOneAndOnlyRequestCallBack(r: [*c]C.http_s) callconv(.C) void { if (the_one_and_only_listener) |l| { var req: SimpleRequest = .{ - .path = fio2str(r.*.path), - .query = fio2str(r.*.query), - .body = fio2str(r.*.body), - .method = fio2str(r.*.method), + .path = util.fio2str(r.*.path), + .query = util.fio2str(r.*.query), + .body = util.fio2str(r.*.body), + .method = util.fio2str(r.*.method), .h = r, }; l.settings.on_request.?(req); diff --git a/targets.txt b/targets.txt index 0e3b52b..e134aac 100644 --- a/targets.txt +++ b/targets.txt @@ -5,3 +5,4 @@ serve hello_json endpoint wrk +mustache