Skip to content

Commit 5a1de9b

Browse files
committed
Update tests slightly and add more detailt o README
1 parent 45451cb commit 5a1de9b

File tree

5 files changed

+77
-92
lines changed

5 files changed

+77
-92
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
11
# ip.zig [![CircleCI](https://circleci.com/gh/euantorano/ip.zig.svg?style=svg)](https://circleci.com/gh/euantorano/ip.zig)
22

33
A Zig library for working with IP Addresses
4+
5+
## Current Status
6+
7+
- [X] Constructing IPv4/IPv6 addresses from octets or bytes
8+
- [X] IpAddress union
9+
- [X] Various utility methods for working with IP addresses, such as: comparing for equality; checking for loopback/multicast/globally routable
10+
- [X] Formatting IPv4/IPv6 addresses using `std.format`
11+
- [ ] Parsing IPv4/IPv6 addresses from strings
12+
- [X] Parsing IPv4 addresses
13+
- [ ] Parsing IPv6 addresses
14+
- [X] Parsing simple IPv6 addresses
15+
- [ ] Parsing IPv4 compatible/mapped IPv6 addresses
16+
- [ ] Parsing IPv6 address scopes (`scope id`)

src/main.zig

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ pub const IpV6Address = struct {
264264
var address: [16]u8 = undefined;
265265
mem.writeInt(u128, &address, ip, builtin.Endian.Big);
266266

267-
return Self.from_slice(&address);
267+
return Self.from_array(address);
268268
}
269269

270270
fn parse_as_many_octets_as_possible(buf: []const u8, parsed_to: *usize) ParseError![]u16 {
@@ -296,7 +296,7 @@ pub const IpV6Address = struct {
296296
if (i > 0) {
297297
octets_index += 1;
298298
}
299-
299+
300300
any_digits = false;
301301
},
302302
'0'...'9', 'a'...'z', 'A'...'Z' => {
@@ -314,7 +314,7 @@ pub const IpV6Address = struct {
314314
},
315315
else => {
316316
return ParseError.InvalidCharacter;
317-
}
317+
},
318318
};
319319

320320
if (@mulWithOverflow(u16, x, 16, &x)) {
@@ -348,16 +348,7 @@ pub const IpV6Address = struct {
348348

349349
if (first_part.len == 8) {
350350
// got all octets, meaning there is no empty section within the string
351-
parsed = Self.init(
352-
first_part[0],
353-
first_part[1],
354-
first_part[2],
355-
first_part[3],
356-
first_part[4],
357-
first_part[5],
358-
first_part[6],
359-
first_part[7]
360-
);
351+
parsed = Self.init(first_part[0], first_part[1], first_part[2], first_part[3], first_part[4], first_part[5], first_part[6], first_part[7]);
361352
} else {
362353
// not all octets parsed, there must be more to parse
363354
if (parsed_to >= buf.len) {
@@ -372,21 +363,12 @@ pub const IpV6Address = struct {
372363
std.mem.copy(u16, octs[0..first_part.len], first_part);
373364
}
374365

375-
const end_buf = buf[parsed_to + 1..];
366+
const end_buf = buf[parsed_to + 1 ..];
376367
const second_part = try Self.parse_as_many_octets_as_possible(end_buf, &parsed_to);
377368

378-
std.mem.copy(u16, octs[8 - second_part.len..], second_part);
379-
380-
parsed = Self.init(
381-
octs[0],
382-
octs[1],
383-
octs[2],
384-
octs[3],
385-
octs[4],
386-
octs[5],
387-
octs[6],
388-
octs[7]
389-
);
369+
std.mem.copy(u16, octs[8 - second_part.len ..], second_part);
370+
371+
parsed = Self.init(octs[0], octs[1], octs[2], octs[3], octs[4], octs[5], octs[6], octs[7]);
390372
}
391373

392374
if (parsed_to < buf.len - 1) {

test/ipv4.zig

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,46 +24,46 @@ test "IpV4Address.octets()" {
2424
}
2525

2626
test "IpV4Address.is_unspecified()" {
27-
testing.expect(IpV4Address.init(0, 0, 0, 0).is_unspecified() == true);
27+
testing.expect(IpV4Address.init(0, 0, 0, 0).is_unspecified());
2828
testing.expect(IpV4Address.init(192, 168, 0, 1).is_unspecified() == false);
2929
}
3030

3131
test "IpV4Address.is_loopback()" {
32-
testing.expect(IpV4Address.init(127, 0, 0, 1).is_loopback() == true);
32+
testing.expect(IpV4Address.init(127, 0, 0, 1).is_loopback());
3333
testing.expect(IpV4Address.init(192, 168, 0, 1).is_loopback() == false);
3434
}
3535

3636
test "IpV4Address.is_private()" {
37-
testing.expect(IpV4Address.init(10, 0, 0, 1).is_private() == true);
38-
testing.expect(IpV4Address.init(10, 10, 10, 10).is_private() == true);
39-
testing.expect(IpV4Address.init(172, 16, 10, 10).is_private() == true);
40-
testing.expect(IpV4Address.init(172, 29, 45, 14).is_private() == true);
37+
testing.expect(IpV4Address.init(10, 0, 0, 1).is_private());
38+
testing.expect(IpV4Address.init(10, 10, 10, 10).is_private());
39+
testing.expect(IpV4Address.init(172, 16, 10, 10).is_private());
40+
testing.expect(IpV4Address.init(172, 29, 45, 14).is_private());
4141
testing.expect(IpV4Address.init(172, 32, 0, 2).is_private() == false);
42-
testing.expect(IpV4Address.init(192, 168, 0, 2).is_private() == true);
42+
testing.expect(IpV4Address.init(192, 168, 0, 2).is_private());
4343
testing.expect(IpV4Address.init(192, 169, 0, 2).is_private() == false);
4444
}
4545

4646
test "IpV4Address.is_link_local()" {
47-
testing.expect(IpV4Address.init(169, 254, 0, 0).is_link_local() == true);
48-
testing.expect(IpV4Address.init(169, 254, 10, 65).is_link_local() == true);
47+
testing.expect(IpV4Address.init(169, 254, 0, 0).is_link_local());
48+
testing.expect(IpV4Address.init(169, 254, 10, 65).is_link_local());
4949
testing.expect(IpV4Address.init(16, 89, 10, 65).is_link_local() == false);
5050
}
5151

5252
test "IpV4Address.is_multicast()" {
53-
testing.expect(IpV4Address.init(224, 254, 0, 0).is_multicast() == true);
54-
testing.expect(IpV4Address.init(236, 168, 10, 65).is_multicast() == true);
53+
testing.expect(IpV4Address.init(224, 254, 0, 0).is_multicast());
54+
testing.expect(IpV4Address.init(236, 168, 10, 65).is_multicast());
5555
testing.expect(IpV4Address.init(172, 16, 10, 65).is_multicast() == false);
5656
}
5757

5858
test "IpV4Address.is_broadcast()" {
59-
testing.expect(IpV4Address.init(255, 255, 255, 255).is_broadcast() == true);
59+
testing.expect(IpV4Address.init(255, 255, 255, 255).is_broadcast());
6060
testing.expect(IpV4Address.init(236, 168, 10, 65).is_broadcast() == false);
6161
}
6262

6363
test "IpV4Address.is_documentation()" {
64-
testing.expect(IpV4Address.init(192, 0, 2, 255).is_documentation() == true);
65-
testing.expect(IpV4Address.init(198, 51, 100, 65).is_documentation() == true);
66-
testing.expect(IpV4Address.init(203, 0, 113, 6).is_documentation() == true);
64+
testing.expect(IpV4Address.init(192, 0, 2, 255).is_documentation());
65+
testing.expect(IpV4Address.init(198, 51, 100, 65).is_documentation());
66+
testing.expect(IpV4Address.init(203, 0, 113, 6).is_documentation());
6767
testing.expect(IpV4Address.init(193, 34, 17, 19).is_documentation() == false);
6868
}
6969

@@ -72,16 +72,18 @@ test "IpV4Address.is_globally_routable()" {
7272
testing.expect(IpV4Address.init(192, 168, 10, 65).is_globally_routable() == false);
7373
testing.expect(IpV4Address.init(172, 16, 10, 65).is_globally_routable() == false);
7474
testing.expect(IpV4Address.init(0, 0, 0, 0).is_globally_routable() == false);
75-
testing.expect(IpV4Address.init(80, 9, 12, 3).is_globally_routable() == true);
75+
testing.expect(IpV4Address.init(80, 9, 12, 3).is_globally_routable());
7676
}
7777

7878
test "IpV4Address.equals()" {
7979
testing.expect(IpV4Address.init(10, 254, 0, 0).equals(IpV4Address.init(127, 0, 0, 1)) == false);
80-
testing.expect(IpV4Address.init(127, 0, 0, 1).equals(IpV4Address.Localhost) == true);
80+
testing.expect(IpV4Address.init(127, 0, 0, 1).equals(IpV4Address.Localhost));
8181
}
8282

8383
test "IpV4Address.to_host_byte_order()" {
84-
testing.expect(IpV4Address.init(13, 12, 11, 10).to_host_byte_order() == 0x0d0c0b0a);
84+
var expected: u32 = 0x0d0c0b0a;
85+
86+
testing.expectEqual(expected, IpV4Address.init(13, 12, 11, 10).to_host_byte_order());
8587
}
8688

8789
test "IpV4Address.from_host_byte_order()" {
@@ -98,15 +100,11 @@ test "IpV4Address.format()" {
98100

99101
const expected: []const u8 = "13.12.11.10";
100102

101-
testing.expect(mem.eql(u8, result, expected));
103+
testing.expectEqualSlices(u8, expected, result);
102104
}
103105

104106
fn testIpV4ParseError(addr: []const u8, expected_error: ParseError) void {
105-
if (IpV4Address.parse(addr)) |_| {
106-
@panic("parse success, expected failure");
107-
} else |e| {
108-
testing.expect(e == expected_error);
109-
}
107+
testing.expectError(expected_error, IpV4Address.parse(addr));
110108
}
111109

112110
fn testIpV4Format(addr: IpV4Address, expected: []const u8) !void {
@@ -115,7 +113,7 @@ fn testIpV4Format(addr: IpV4Address, expected: []const u8) !void {
115113

116114
const result = try fmt.bufPrint(buf, "{}", addr);
117115

118-
testing.expect(mem.eql(u8, result, expected));
116+
testing.expectEqualSlices(u8, expected, result);
119117
}
120118

121119
test "IpV4Address.parse()" {

test/ipv6.zig

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,44 +30,44 @@ test "IpV6Address.from_slice()" {
3030
}
3131

3232
test "IpV6Address.is_unspecified()" {
33-
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0, 0, 0).is_unspecified() == true);
33+
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0, 0, 0).is_unspecified());
3434
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unspecified() == false);
3535
}
3636

3737
test "IpV6Address.is_loopback()" {
38-
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0, 0, 0x1).is_loopback() == true);
38+
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0, 0, 0x1).is_loopback());
3939
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_loopback() == false);
4040
}
4141

4242
test "IpV6Address.is_multicast()" {
43-
testing.expect(IpV6Address.init(0xff00, 0, 0, 0, 0, 0, 0, 0).is_multicast() == true);
43+
testing.expect(IpV6Address.init(0xff00, 0, 0, 0, 0, 0, 0, 0).is_multicast());
4444
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_multicast() == false);
4545
}
4646

4747
test "IpV6Address.is_documentation()" {
48-
testing.expect(IpV6Address.init(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_documentation() == true);
48+
testing.expect(IpV6Address.init(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_documentation());
4949
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_documentation() == false);
5050
}
5151

5252
test "IpV6Address.is_multicast_link_local()" {
5353
var arr = []u8{ 0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02 };
5454

55-
testing.expect(IpV6Address.from_slice(&arr).is_multicast_link_local() == true);
55+
testing.expect(IpV6Address.from_slice(&arr).is_multicast_link_local());
5656
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_multicast_link_local() == false);
5757
}
5858

5959
test "IpV6Address.is_unicast_site_local()" {
60-
testing.expect(IpV6Address.init(0xfec2, 0, 0, 0, 0, 0, 0, 0).is_unicast_site_local() == true);
60+
testing.expect(IpV6Address.init(0xfec2, 0, 0, 0, 0, 0, 0, 0).is_unicast_site_local());
6161
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_site_local() == false);
6262
}
6363

6464
test "IpV6Address.is_unicast_link_local()" {
65-
testing.expect(IpV6Address.init(0xfe8a, 0, 0, 0, 0, 0, 0, 0).is_unicast_link_local() == true);
65+
testing.expect(IpV6Address.init(0xfe8a, 0, 0, 0, 0, 0, 0, 0).is_unicast_link_local());
6666
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_link_local() == false);
6767
}
6868

6969
test "IpV6Address.is_unique_local()" {
70-
testing.expect(IpV6Address.init(0xfc02, 0, 0, 0, 0, 0, 0, 0).is_unique_local() == true);
70+
testing.expect(IpV6Address.init(0xfc02, 0, 0, 0, 0, 0, 0, 0).is_unique_local());
7171
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unique_local() == false);
7272
}
7373

@@ -79,13 +79,13 @@ test "IpV6Address.multicast_scope()" {
7979
}
8080

8181
test "IpV6Address.is_globally_routable()" {
82-
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_globally_routable() == true);
83-
testing.expect(IpV6Address.init(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1).is_globally_routable() == true);
82+
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_globally_routable());
83+
testing.expect(IpV6Address.init(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1).is_globally_routable());
8484
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0, 0, 0x1).is_globally_routable() == false);
8585
}
8686

8787
test "IpV6Address.is_unicast_global()" {
88-
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_global() == true);
88+
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_global());
8989
testing.expect(IpV6Address.init(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_unicast_global() == false);
9090
}
9191

@@ -99,14 +99,14 @@ test "IpV6Address.to_ipv4()" {
9999
}
100100

101101
test "IpV6Address.equals()" {
102-
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0, 0, 1).equals(IpV6Address.Localhost) == true);
102+
testing.expect(IpV6Address.init(0, 0, 0, 0, 0, 0, 0, 1).equals(IpV6Address.Localhost));
103103
}
104104

105105
test "IpV6Address.to_host_byte_order()" {
106106
const addr = IpV6Address.init(0x1020, 0x3040, 0x5060, 0x7080, 0x90A0, 0xB0C0, 0xD0E0, 0xF00D);
107107
const expected: u128 = 0x102030405060708090A0B0C0D0E0F00D;
108108

109-
testing.expect(addr.to_host_byte_order() == expected);
109+
testing.expectEqual(expected, addr.to_host_byte_order());
110110
}
111111

112112
test "IpV6Address.from_host_byte_order()" {
@@ -122,7 +122,7 @@ fn test_format_ipv6_address(address: IpV6Address, expected: []const u8) !void {
122122

123123
const result = try fmt.bufPrint(buf, "{}", address);
124124

125-
testing.expect(mem.eql(u8, result, expected));
125+
testing.expectEqualSlices(u8, expected, result);
126126
}
127127

128128
test "IpV6Address.format()" {
@@ -143,11 +143,7 @@ test "IpV6Address.format()" {
143143
}
144144

145145
fn testIpV6ParseError(addr: []const u8, expected_error: ParseError) void {
146-
if (IpV6Address.parse(addr)) |_| {
147-
@panic("parse success, expected failure");
148-
} else |e| {
149-
testing.expect(e == expected_error);
150-
}
146+
testing.expectError(expected_error, IpV6Address.parse(addr));
151147
}
152148

153149
fn testIpV6Format(addr: IpV6Address, expected: []const u8) !void {
@@ -156,7 +152,7 @@ fn testIpV6Format(addr: IpV6Address, expected: []const u8) !void {
156152

157153
const result = try fmt.bufPrint(buf, "{}", addr);
158154

159-
testing.expect(mem.eql(u8, result, expected));
155+
testing.expectEqualSlices(u8, expected, result);
160156
}
161157

162158
fn testIpV6ParseAndBack(addr: []const u8, expectedIp: IpV6Address) !void {

0 commit comments

Comments
 (0)