pub const OSC52 = @import("Clip/OSC52.zig"); // pub const PBCopy = if (@import("builtin").os.tag == .macos) @import("Clip/OSC52.zig") else null; // I am not sure if this is super idiomatic Zig or if this is bad practice, but // by ensuring that all Clip backends implement the same methods, we are able // to use the `anytype` type and we are able to have an interface that is able // to dispatch statically /// Check if a function with the given name and type exists. /// `@compileError` if not fn assertFn(comptime T: type, comptime name: []const u8, comptime Sig: type) void { if (!@import("std").meta.hasFn(T, name)) @compileError(@typeName(T) ++ " missing fn " ++ name); if (@TypeOf(@field(T, name)) != Sig) @compileError(@typeName(T) ++ "." ++ name ++ " must be " ++ @typeName(Sig)); } test { _ = @import("Clip/NSPasteBoard.zig"); inline for (@typeInfo(@This()).@"struct".decls) |decl| { // Only grab types of structs const T = @field(@This(), decl.name); if (@TypeOf(T) != type) continue; if (@typeInfo(T) != .@"struct") continue; // ============================== // === Interface Requirements === // ============================== assertFn(T, "writeCopyBuffer", fn (*T, []const u8) anyerror!void); assertFn(T, "writePasteboard", fn (*T) anyerror!void); } }