const c = @cImport({ @cInclude("zaprus.h"); }); fn zigToCMessage(msg: ?*zaprus.Message) ?*c.SaprusMessage { if (msg) |m| { return switch (m.*) { .relay => |_| @constCast(&c.SaprusMessage{}), .connection => |_| @constCast(&c.SaprusMessage{}), else => |_| null, }; } else return null; } fn cToZigMessage(msg: ?*c.SaprusMessage) ?*zaprus.Message { _ = msg; return @constCast(&zaprus.Message{ .relay = .{ .header = .{ .dest = @splat(0) }, .payload = &.{0}, }, }); } // client export fn zaprus_init() c_int { SaprusClient.init() catch return 1; return 0; } export fn zaprus_deinit() c_int { SaprusClient.deinit(); return 0; } export fn zaprus_send_relay(payload: [*]const u8, len: usize, dest: [*]u8) c_int { SaprusClient.sendRelay(payload[0..len], dest[0..4].*, allocator) catch return 1; return 0; } export fn zaprus_send_initial_connection(payload: [*]const u8, len: usize, initial_port: u16) c_int { _ = SaprusClient.sendInitialConnection(payload[0..len], initial_port, allocator) catch return 1; return 0; } export fn zaprus_connect(payload: [*]const u8, len: usize) ?*c.SaprusMessage { if (SaprusClient.connect(payload[0..len], allocator)) |msg| { return zigToCMessage(@constCast(&(msg.?))); } else |_| { return null; } } // message /// ptr should be freed by the caller. export fn zaprus_message_to_bytes(msg: c.SaprusMessage, ptr: *[*]u8, len: *usize) c_int { if (cToZigMessage(@constCast(&msg))) |m| { const bytes = m.toBytes(allocator) catch return 1; ptr.* = bytes.ptr; len.* = bytes.len; return 0; } else return 1; } /// Return value should be destroyed with zaprus_message_deinit. export fn zaprus_message_from_bytes(bytes: [*]const u8, len: usize) ?*c.SaprusMessage { if (zaprus.Message.fromBytes(bytes[0..len], allocator)) |msg| { return zigToCMessage(@constCast(&msg)); } else |_| return null; } export fn zaprus_message_deinit(msg: *c.SaprusMessage) void { // noop _ = msg; // msg.*.deinit(allocator); } const std = @import("std"); const zaprus = @import("./root.zig"); const SaprusClient = zaprus.Client; // const SaprusMessage = zaprus.Message; const allocator = std.heap.c_allocator; test { std.testing.refAllDeclsRecursively(@This()); }