master
 1const std = @import("std");
 2const uefi = std.os.uefi;
 3const Guid = uefi.Guid;
 4const Handle = uefi.Handle;
 5const Status = uefi.Status;
 6const Error = Status.Error;
 7const cc = uefi.cc;
 8
 9pub fn ServiceBinding(service_guid: Guid) type {
10    return struct {
11        const Self = @This();
12
13        _create_child: *const fn (*Self, *?Handle) callconv(cc) Status,
14        _destroy_child: *const fn (*Self, Handle) callconv(cc) Status,
15
16        pub const CreateChildError = uefi.UnexpectedError || error{
17            InvalidParameter,
18            OutOfResources,
19        } || Error;
20        pub const DestroyChildError = uefi.UnexpectedError || error{
21            Unsupported,
22            InvalidParameter,
23            AccessDenied,
24        } || Error;
25
26        /// To add this protocol to an existing handle, use `addToHandle` instead.
27        pub fn createChild(self: *Self) CreateChildError!Handle {
28            var handle: ?Handle = null;
29            switch (self._create_child(self, &handle)) {
30                .success => return handle orelse error.Unexpected,
31                else => |status| {
32                    try status.err();
33                    return uefi.unexpectedStatus(status);
34                },
35            }
36        }
37
38        pub fn addToHandle(self: *Self, handle: Handle) CreateChildError!void {
39            switch (self._create_child(self, @ptrCast(@constCast(&handle)))) {
40                .success => {},
41                else => |status| {
42                    try status.err();
43                    return uefi.unexpectedStatus(status);
44                },
45            }
46        }
47
48        pub fn destroyChild(self: *Self, handle: Handle) DestroyChildError!void {
49            switch (self._destroy_child(self, handle)) {
50                .success => {},
51                else => |status| {
52                    try status.err();
53                    return uefi.unexpectedStatus(status);
54                },
55            }
56        }
57
58        pub const guid align(8) = service_guid;
59    };
60}