I’ve been internally using a library for IP and Mac addresses, and thought I’d open source the toolset. Some of the more interesting features include
- guard clauses
- support for CIDR block notation and ease of generating ipv4 broadcast addresses
- sigil_i for IP addresses, ranges, and support for matching pinned variables (useful for /24 addresses)
Pretty useful, thanks for that.
I would only change
parse!/1 instead to match the
Float API more closely.
Parse returns a tuple that contains an extra binary useful for unit matching, no?
Yes, but in general I would assume
IP.parse/1) to return error tuple instead of throwing on error. You can pick any naming, but I would expect to have “failure-safe” way to parse data.
I think in elixir, .to_x and .from_x are designed to output naked values (String.to_integer/1 raises on a non-integer string), and be in pipelines, but your point about wanting something that outputs an error tuple on conversion is taken under advisement! https://github.com/ityonemo/net_address/issues/1
While you are generally correct I believe that having a bang variant like
parse! signals even more clearly that the function might raise an exception which also implies that
parse would return an ok/error tuple.
As another anecdotal evidence data point, I would also naively believe that
from_string would not raise and would return an ok/error tuple as well (although this expectation might be severely misguided – I really don’t know).
The standard library’s Map.from_struct/1 does not return an error tuple. But doing a more comprehensive look, I see that the datetime/time/naivedatetime modules have from_* functions which do emit error tuples. I guess network addresses seem more like datetimes than structs, so I’ll go ahead and make the from_ functions emit tuples and have the bang equivalents throw.
updated in 0.2.0 to have bang functions and tuple functions for from_* functions, and as a bonus I implemented random and IP.SockAddr module.
I like how you used the
m modifier on
sigil_i. Nice touch.
updated in 0.3.0 to have ranges and subnets work in each other’s
Kernel.in/2 implementations; also implements
is_in function to detect membership in ranges and subnets, in guards.