lib/sys/src/apple/foundation.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2 const apple = @import("root.zig");
3
4 pub const NSUInteger = u64;
5 pub const NSInteger = i64;
6 pub const String = *opaque {};
7 pub const Error = *opaque {};
8
9 const utf8_string_encoding: NSUInteger = 4;
10
11 pub const AutoreleasePool = struct {
12 handle: apple.objc.Id,
13
14 pub fn init() ?AutoreleasePool {
15 const pool_class = apple.objc.class("NSAutoreleasePool") orelse return null;
16 const allocated = apple.objc.send(?apple.objc.Id, pool_class, apple.objc.selector("alloc"), .{}) orelse return null;
17 const initialized = apple.objc.send(?apple.objc.Id, allocated, apple.objc.selector("init"), .{}) orelse return null;
18 return .{ .handle = initialized };
19 }
20
21 pub fn deinit(self: *AutoreleasePool) void {
22 apple.objc.send(void, self.handle, apple.objc.selector("drain"), .{});
23 self.* = undefined;
24 }
25 };
26
27 pub fn stringFromBytes(bytes: []const u8) ?String {
28 if (bytes.len == 0) return null;
29 const string_class = apple.objc.class("NSString") orelse return null;
30 const allocated = apple.objc.send(?apple.objc.Id, string_class, apple.objc.selector("alloc"), .{}) orelse return null;
31 return apple.objc.send(
32 ?String,
33 allocated,
34 apple.objc.selector("initWithBytes:length:encoding:"),
35 .{ bytes.ptr, bytes.len, utf8_string_encoding },
36 );
37 }
38
39 /// The string's UTF-8 bytes, valid while the string lives and the current autorelease pool stands.
40 pub fn utf8(string: String) ?[*:0]const u8 {
41 return apple.objc.send(?[*:0]const u8, @ptrCast(string), apple.objc.selector("UTF8String"), .{});
42 }
43
44 /// The error's localized description, autoreleased.
45 pub fn errorDescription(error_object: Error) ?String {
46 return apple.objc.send(?String, @ptrCast(error_object), apple.objc.selector("localizedDescription"), .{});
47 }
48
49 pub fn errorCode(error_object: Error) NSInteger {
50 return apple.objc.send(NSInteger, @ptrCast(error_object), apple.objc.selector("code"), .{});
51 }
52
53 test "Foundation uses the 64-bit Apple scalar ABI" {
54 try std.testing.expectEqual(@as(usize, 8), @sizeOf(NSUInteger));
55 try std.testing.expectEqual(@as(usize, 8), @sizeOf(NSInteger));
56 try std.testing.expectEqual(@sizeOf(usize), @sizeOf(String));
57 try std.testing.expectEqual(@sizeOf(usize), @sizeOf(Error));
58 try std.testing.expectEqual(@sizeOf(usize), @sizeOf(AutoreleasePool));
59 }