splitNotation(notation: string): Notation
Splits an IP notation string into its address, zone ID and prefix slots.
One pass over the string records where % and / are, then slices.
Nothing about IP is checked here; the parsers that call this do that on
the slices. Exactly five shapes are rejected, all TypeError:
%more than once:fe80::1%eth0%1/more than once:10.0.0.0/8/8%after/:10.0.0.0/8%eth0(RFC 4007 section 11.7 puts the zone first)- an empty address:
%eth0,/64 - an empty zone ID or prefix:
fe80::1%,10.0.0.0/
Because no slot may contain % or /, both positions are unique, and
the zone slice ends at the / rather than running to the end of the
string. fe80::1%eth0/64 is therefore the zone eth0 with the prefix
64; there is no greedy reading to get wrong.
An address alone
An address alone
import { assertEquals } from "@std/assert"; import { splitNotation } from "@hertzg/ip/notation"; assertEquals(splitNotation("192.168.1.1"), { address: "192.168.1.1" }); assertEquals(splitNotation("fe80::1"), { address: "fe80::1" });
The zone slice stops at the slash
The zone slice stops at the slash
import { assertEquals } from "@std/assert"; import { splitNotation } from "@hertzg/ip/notation"; assertEquals(splitNotation("fe80::1%eth0/64"), { address: "fe80::1", zoneId: "eth0", prefix: "64", }); assertEquals(splitNotation("fe80::1%eth0.100"), { address: "fe80::1", zoneId: "eth0.100", });
The five rejected shapes
The five rejected shapes
import { assertThrows } from "@std/assert"; import { splitNotation } from "@hertzg/ip/notation"; assertThrows(() => splitNotation("fe80::1%eth0%1"), TypeError); assertThrows(() => splitNotation("10.0.0.0/8/8"), TypeError); assertThrows(() => splitNotation("10.0.0.0/8%eth0"), TypeError); assertThrows(() => splitNotation("%eth0"), TypeError); assertThrows(() => splitNotation("fe80::1%"), TypeError); assertThrows(() => splitNotation("10.0.0.0/"), TypeError);
The three slots as slices; zoneId and prefix are present
only when the string has them