Easy solution for all your zig dynamic dispatch needs!
This project is a fork of interface.zig which aims to port the project to zig 0.14.1 as a fetchable library. It changes certain behavior and naming conventions see Example for details.
- Fully decoupled interfaces and implementations
- Control over the storage/ownership of interface objects
- Comptime support (including comptime-only interfaces)
- Optional function support
- Support for manually written vtables
Run the following command to install into a zig project
> zig fetch --save git+https://github.com/JacobHumphreys/interface.zig.gitThen Add the following to build.zig
const interface_lib_dep = b.dependency("interface", .{});
const interface_lib = interface_lib_dep.module("interface");
const exe = b.addExecutable(.{
//Find this setting
});
//paste this after
exe.root_module.addImport("interface", interface_lib);const std = @import("std");
const interface = @import("interface");
const SelfType = interface.SelfType;
const ExampleInterface = struct{
const Definition = interface.Define(struct {
print: *const fn (*SelfType, []const u8) void,
}, .non_owned);
impl: Definition,
//Inlining is optional
pub inline fn Impl(impl_ptr: anytype) ExampleInterface {
return ExampleInterface{
.impl = Definition.init(impl_ptr),
};
}
//Inlining is optional
pub inline fn print(self: ExampleInterface, message: []const u8) void {
return self.impl.call("print", .{message});
}
};
const ExampleImpl = struct{
property: u32,
pub fn print(self: *ExampleImpl, message: []const u8) void {
std.debug.print("prop: {}\nmessage: {s}\n", .{self.property, message});
}
};
pub fn main() !void {
var exampleStruct = ExampleImpl{
.property = 1,
};
const impl_from_struct: ExampleInterface = ExampleInterface.Impl(&exampleStruct));
callPrintOnExample(impl_from_struct);
}
fn callPrintOnExample(printer: ExampleInterface) void {
printer.print("Interfaces!");
}See example-project directory for full implementation details.
See testing.zig for more examples.