Something went wrong. Try again.
My version of https://github.com/vercel-labs/fx
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142const std = @import("std");
pub const ProcessInstanceToken = struct { bytes: [128]u8 = undefined, len: u8 = 0,
pub fn parse(text: []const u8) !ProcessInstanceToken { if (text.len == 0 or text.len > 128) { return error.InvalidProcessInstanceToken; } for (text) |byte| { if (!std.ascii.isAscii(byte) or std.ascii.isUpper(byte) or std.ascii.isWhitespace(byte) or std.ascii.isControl(byte)) { return error.InvalidProcessInstanceToken; } } var parts = std.mem.splitScalar(u8, text, ':'); const platform = parts.next() orelse return error.InvalidProcessInstanceToken; const boot_id = parts.next() orelse return error.InvalidProcessInstanceToken; if (!isLowerHex(boot_id, 32)) { return error.InvalidProcessInstanceToken; } if (std.mem.eql(u8, platform, "linux")) { const start_ticks = parts.next() orelse return error.InvalidProcessInstanceToken; if (parts.next() != null or !isCanonicalDecimal(start_ticks)) { return error.InvalidProcessInstanceToken; } } else if (std.mem.eql(u8, platform, "macos")) { const start_sec = parts.next() orelse return error.InvalidProcessInstanceToken; const start_usec = parts.next() orelse return error.InvalidProcessInstanceToken; if (parts.next() != null or !isCanonicalDecimal(start_sec) or !isCanonicalDecimal(start_usec)) { return error.InvalidProcessInstanceToken; } } else { return error.InvalidProcessInstanceToken; } var token = ProcessInstanceToken{}; @memcpy(token.bytes[0..text.len], text); token.len = @intCast(text.len); return token; }
pub fn view(self: *const ProcessInstanceToken) []const u8 { return self.bytes[0..self.len]; }
pub fn eql(self: ProcessInstanceToken, other: ProcessInstanceToken) bool { return std.mem.eql(u8, self.view(), other.view()); }};
fn isLowerHex(value: []const u8, expected_len: usize) bool { if (value.len != expected_len) return false; for (value) |byte| { if (!std.ascii.isDigit(byte) and (byte < 'a' or byte > 'f')) { return false; } } return true;}
fn isCanonicalDecimal(value: []const u8) bool { if (value.len == 0) return false; if (value.len > 1 and value[0] == '0') return false; for (value) |byte| { if (!std.ascii.isDigit(byte)) return false; } _ = std.fmt.parseInt(u64, value, 10) catch return false; return true;}
pub const TokenMatch = enum { matched, missing, mismatched, unavailable,};
pub var process_token_match_for_test: ?*const fn ([]const u8, ProcessInstanceToken) TokenMatch = null;pub var process_token_capture_for_test: ?*const fn ( std.mem.Allocator, []const u8,) anyerror!ProcessInstanceToken = null;
pub fn captureProcessInstanceToken( alloc: std.mem.Allocator, pid_text: []const u8,) !ProcessInstanceToken { if (process_token_capture_for_test) |callback| { return callback(alloc, pid_text); } return error.ProcessIdentityUnsupported;}
pub fn matchProcessInstanceToken( alloc: std.mem.Allocator, pid_text: []const u8, expected: ProcessInstanceToken,) TokenMatch { if (process_token_match_for_test) |callback| { return callback(pid_text, expected); } const actual = captureProcessInstanceToken(alloc, pid_text) catch |err| { return switch (err) { error.ProcessNotFound => .missing, else => .unavailable, }; }; return if (actual.eql(expected)) .matched else .mismatched;}
test "process instance tokens are canonical and require exact match" { const token = try ProcessInstanceToken.parse( "linux:00112233445566778899aabbccddeeff:12345", ); try std.testing.expectEqualStrings( "linux:00112233445566778899aabbccddeeff:12345", token.view(), ); try std.testing.expect(token.eql(token)); try std.testing.expectError( error.InvalidProcessInstanceToken, ProcessInstanceToken.parse( "linux:00112233445566778899AABBCCDDEEFF:12345", ), );}