Skip to content

Instantly share code, notes, and snippets.

@jmcph4
Last active September 2, 2023 01:40
Show Gist options
  • Select an option

  • Save jmcph4/477993b411ac4f90f99dd6fa177fccdc to your computer and use it in GitHub Desktop.

Select an option

Save jmcph4/477993b411ac4f90f99dd6fa177fccdc to your computer and use it in GitHub Desktop.
const std = @import("std");
const Allocator = std.mem.Allocator;
const ArrayList = std.ArrayList;
const expect = std.testing.expect;
const PATH_SEPARATOR: c_char = '/';
const Protocol = enum {
dccp,
dns,
dns4,
dns6,
dnsaddr,
http,
https,
ip4,
ip6,
p2pWebRtcDirect,
p2pWebRtcStar,
webRTCDirect,
certhash,
p2pWebSocketStar,
memory,
onion,
onion3,
p2p,
p2pCircuit,
quic,
quicV1,
sctp,
tcp,
tls,
noise,
udp,
udt,
unix,
utp,
webTransport,
ws,
wss,
pub fn to_string(self: Protocol, allocator: Allocator) [:0]const u8 {
try std.fmt.allocPrintZ(allocator, "{}", .{self});
}
pub fn format(value: Protocol, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
try writer.print("{s}", .{@tagName(value)});
}
};
const MultiaddrSegment = struct {
proto: Protocol,
data: []const u8,
pub fn init(protocol: Protocol, data: []const u8) MultiaddrSegment {
return MultiaddrSegment{
.proto = protocol,
.data = data,
};
}
fn format(value: MultiaddrSegment, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
try writer.print("{c}{s}{c}{s}", .{ PATH_SEPARATOR, value.proto.to_string(), PATH_SEPARATOR, value.value.to_string() });
}
fn to_string(self: *MultiaddrSegment, allocator: Allocator) ![:0]const u8 {
return try std.fmt.allocPrintZ(allocator, "{}", .{self});
}
};
const Multiaddr = struct {
segments: ArrayList(MultiaddrSegment),
alloc: Allocator,
pub fn init(allocator: Allocator) Multiaddr {
return Multiaddr{
.segments = std.ArrayList(MultiaddrSegment).init(allocator),
.alloc = allocator,
};
}
pub fn deinit(self: *Multiaddr) void {
self.segments.deinit();
}
pub fn num_segments(self: *Multiaddr) usize {
return self.segments.len();
}
pub fn empty(self: *Multiaddr) bool {
return self.segments.len() == 0;
}
pub fn push(self: *Multiaddr, segment: MultiaddrSegment) !void {
try self.segments.append(segment);
}
pub fn to_string(self: *Multiaddr, allocator: Allocator) ![:0]const u8 {
return try std.fmt.allocPrintZ(allocator, "{}", .{self});
}
fn format(value: Multiaddr, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
for (value.segments.items) |curr_seg| {
try writer.print("{}", .{curr_seg});
}
}
};
test "serialise normal segment to string" {
var alloc: Allocator = std.testing.allocator;
var seg: MultiaddrSegment = MultiaddrSegment.init(Protocol.ip4, "127.0.0.1");
var actual_str: [:0]const u8 = try seg.to_string(alloc);
const expected_str: [:0]const u8 = "/ip4/127.0.0.1";
defer alloc.free(actual_str);
try std.testing.expectEqualStrings(expected_str, actual_str);
}
test "serialise normal 2-segment multiaddr to string" {
var alloc: Allocator = std.testing.allocator;
var ipv4_seg: MultiaddrSegment = MultiaddrSegment.init(Protocol.ip4, "127.0.0.1");
var tcp_seg: MultiaddrSegment = MultiaddrSegment.init(Protocol.tcp, "80");
var multiaddr: Multiaddr = Multiaddr.init(alloc);
defer multiaddr.deinit();
try multiaddr.push(ipv4_seg);
try multiaddr.push(tcp_seg);
var actual_str: [:0]const u8 = try multiaddr.to_string(alloc);
const expected_str: [:0]const u8 = "/ip4/127.0.0.1/tcp/80";
defer alloc.free(actual_str);
try std.testing.expectEqualStrings(expected_str, actual_str);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment