aboutsummaryrefslogtreecommitdiff
path: root/src/string_types.zig
blob: 02f692629c990192b1f773480412e1a412e648b1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
const std = @import("std");
pub const string = []const u8;
pub const stringMutable = []u8;
pub const CodePoint = i32;

// macOS sets file path limit to 1024
// Since a pointer on x64 is 64 bits and only 46 bits are used
// We can safely store the entire path slice in a single u64.
pub const PathString = packed struct {
    const PathIntLen = std.math.IntFittingRange(0, std.fs.MAX_PATH_BYTES);
    pub const use_small_path_string = @bitSizeOf(usize) - @bitSizeOf(PathIntLen) >= 53;
    pub const PathInt = if (use_small_path_string) PathIntLen else usize;
    pub const PointerIntType = if (use_small_path_string) u53 else usize;
    ptr: PointerIntType,
    len: PathInt,

    pub inline fn slice(this: PathString) string {
        @setRuntimeSafety(false); // "cast causes pointer to be null" is fine here. if it is null, the len will be 0.
        return @intToPtr([*]u8, @intCast(usize, this.ptr))[0..this.len];
    }

    pub inline fn init(str: string) PathString {
        @setRuntimeSafety(false); // "cast causes pointer to be null" is fine here. if it is null, the len will be 0.

        return PathString{
            .ptr = @truncate(PointerIntType, @ptrToInt(str.ptr)),
            .len = @truncate(PathInt, str.len),
        };
    }

    pub inline fn isEmpty(this: PathString) bool {
        return this.len == 0;
    }

    pub const empty = PathString{ .ptr = 0, .len = 0 };
    comptime {
        if (use_small_path_string and @bitSizeOf(PathString) != 64) {
            @compileError("PathString must be 64 bits");
        } else if (!use_small_path_string and @bitSizeOf(PathString) != 128) {
            @compileError("PathString must be 128 bits");
        }
    }
};