mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-25 13:16:11 +03:00
os/hostname: add and use explicit error structs
This commit is contained in:
@ -1,11 +1,21 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const posix = std.posix;
|
const posix = std.posix;
|
||||||
|
|
||||||
pub fn bufPrintHostnameFromFileUri(buf: []u8, uri: std.Uri) ![]const u8 {
|
const HostnameParsingError = error{
|
||||||
|
NoHostnameInUri,
|
||||||
|
NoSpaceLeft,
|
||||||
|
};
|
||||||
|
|
||||||
|
const LocalHostnameValidationError = error{
|
||||||
|
PermissionDenied,
|
||||||
|
Unexpected,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn bufPrintHostnameFromFileUri(buf: []u8, uri: std.Uri) HostnameParsingError![]const u8 {
|
||||||
// Get the raw string of the URI. Its unclear to me if the various
|
// Get the raw string of the URI. Its unclear to me if the various
|
||||||
// tags of this enum guarantee no percent-encoding so we just
|
// tags of this enum guarantee no percent-encoding so we just
|
||||||
// check all of it. This isn't a performance critical path.
|
// check all of it. This isn't a performance critical path.
|
||||||
const host_component = uri.host orelse return error.NoHostnameInUri;
|
const host_component = uri.host orelse return HostnameParsingError.NoHostnameInUri;
|
||||||
const host = switch (host_component) {
|
const host = switch (host_component) {
|
||||||
.raw => |v| v,
|
.raw => |v| v,
|
||||||
.percent_encoded => |v| v,
|
.percent_encoded => |v| v,
|
||||||
@ -34,7 +44,7 @@ pub fn bufPrintHostnameFromFileUri(buf: []u8, uri: std.Uri) ![]const u8 {
|
|||||||
|
|
||||||
var fbs = std.io.fixedBufferStream(buf);
|
var fbs = std.io.fixedBufferStream(buf);
|
||||||
std.fmt.format(fbs.writer().any(), "{s}:{d}", .{ host, port }) catch |err| switch (err) {
|
std.fmt.format(fbs.writer().any(), "{s}:{d}", .{ host, port }) catch |err| switch (err) {
|
||||||
error.NoSpaceLeft => return error.NoSpaceLeft,
|
error.NoSpaceLeft => return HostnameParsingError.NoSpaceLeft,
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -44,7 +54,7 @@ pub fn bufPrintHostnameFromFileUri(buf: []u8, uri: std.Uri) ![]const u8 {
|
|||||||
return host;
|
return host;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn isLocalHostname(hostname: []const u8) !bool {
|
pub fn isLocalHostname(hostname: []const u8) LocalHostnameValidationError!bool {
|
||||||
// A 'localhost' hostname is always considered local.
|
// A 'localhost' hostname is always considered local.
|
||||||
if (std.mem.eql(u8, "localhost", hostname)) {
|
if (std.mem.eql(u8, "localhost", hostname)) {
|
||||||
return true;
|
return true;
|
||||||
@ -52,8 +62,9 @@ pub fn isLocalHostname(hostname: []const u8) !bool {
|
|||||||
|
|
||||||
// If hostname is not "localhost" it must match our hostname.
|
// If hostname is not "localhost" it must match our hostname.
|
||||||
var buf: [posix.HOST_NAME_MAX]u8 = undefined;
|
var buf: [posix.HOST_NAME_MAX]u8 = undefined;
|
||||||
const ourHostname = posix.gethostname(&buf) catch |err| {
|
const ourHostname = posix.gethostname(&buf) catch |err| switch (err) {
|
||||||
return err;
|
error.PermissionDenied => return LocalHostnameValidationError.PermissionDenied,
|
||||||
|
error.Unexpected => return LocalHostnameValidationError.Unexpected,
|
||||||
};
|
};
|
||||||
|
|
||||||
return std.mem.eql(u8, hostname, ourHostname);
|
return std.mem.eql(u8, hostname, ourHostname);
|
||||||
@ -103,6 +114,24 @@ test "bufPrintHostnameFromFileUri returns only hostname when there is a port com
|
|||||||
try std.testing.expectEqualStrings("12:34:56:78:90:12", mac_with_port_actual);
|
try std.testing.expectEqualStrings("12:34:56:78:90:12", mac_with_port_actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "bufPrintHostnameFromFileUri returns NoHostnameInUri error when hostname is missing from uri" {
|
||||||
|
const uri = try std.Uri.parse("file:///");
|
||||||
|
|
||||||
|
var buf: [posix.HOST_NAME_MAX]u8 = undefined;
|
||||||
|
const actual = bufPrintHostnameFromFileUri(&buf, uri);
|
||||||
|
|
||||||
|
try std.testing.expectError(HostnameParsingError.NoHostnameInUri, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "bufPrintHostnameFromFileUri returns NoSpaceLeft error when provided buffer has insufficient size" {
|
||||||
|
const uri = try std.Uri.parse("file://12:34:56:78:90:12/");
|
||||||
|
|
||||||
|
var buf: [5]u8 = undefined;
|
||||||
|
const actual = bufPrintHostnameFromFileUri(&buf, uri);
|
||||||
|
|
||||||
|
try std.testing.expectError(HostnameParsingError.NoSpaceLeft, actual);
|
||||||
|
}
|
||||||
|
|
||||||
test "isLocalHostname returns true when provided hostname is localhost" {
|
test "isLocalHostname returns true when provided hostname is localhost" {
|
||||||
try std.testing.expect(try isLocalHostname("localhost"));
|
try std.testing.expect(try isLocalHostname("localhost"));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user