aboutsummaryrefslogtreecommitdiff
path: root/lib/std/x/net/ip.zig
blob: a3f5dfecf6ee310a69345eec9020acadf0f0c63f (plain)
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
const std = @import("../../std.zig");

const fmt = std.fmt;

const IPv4 = std.x.os.IPv4;
const IPv6 = std.x.os.IPv6;
const Socket = std.x.os.Socket;

/// A generic IP abstraction.
const ip = @This();

/// A union of all eligible types of IP addresses.
pub const Address = union(enum) {
    ipv4: IPv4.Address,
    ipv6: IPv6.Address,

    /// Instantiate a new address with a IPv4 host and port.
    pub fn initIPv4(host: IPv4, port: u16) Address {
        return .{ .ipv4 = .{ .host = host, .port = port } };
    }

    /// Instantiate a new address with a IPv6 host and port.
    pub fn initIPv6(host: IPv6, port: u16) Address {
        return .{ .ipv6 = .{ .host = host, .port = port } };
    }

    /// Re-interpret a generic socket address into an IP address.
    pub fn from(address: Socket.Address) ip.Address {
        return switch (address) {
            .ipv4 => |ipv4_address| .{ .ipv4 = ipv4_address },
            .ipv6 => |ipv6_address| .{ .ipv6 = ipv6_address },
        };
    }

    /// Re-interpret an IP address into a generic socket address.
    pub fn into(self: ip.Address) Socket.Address {
        return switch (self) {
            .ipv4 => |ipv4_address| .{ .ipv4 = ipv4_address },
            .ipv6 => |ipv6_address| .{ .ipv6 = ipv6_address },
        };
    }

    /// Implements the `std.fmt.format` API.
    pub fn format(
        self: ip.Address,
        comptime layout: []const u8,
        opts: fmt.FormatOptions,
        writer: anytype,
    ) !void {
        _ = opts;
        _ = layout;
        switch (self) {
            .ipv4 => |address| try fmt.format(writer, "{}:{}", .{ address.host, address.port }),
            .ipv6 => |address| try fmt.format(writer, "{}:{}", .{ address.host, address.port }),
        }
    }
};