Skip to content

Commit

Permalink
Merge pull request #17 from go-addrs/implement-missing
Browse files Browse the repository at this point in the history
Implement missing functions
  • Loading branch information
ecbaldwin authored Jun 5, 2024
2 parents f0dc92e + 0bdb33d commit ee24ff4
Show file tree
Hide file tree
Showing 14 changed files with 84 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.test
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
all: test vet fmt
all: build test vet fmt

build:
go build ./...
.PHONY: build

test:
go test -c ./ip
go test -c ./ipv4
go test -c ./ipv6
go test -v ./...
.PHONY: test

Expand Down
2 changes: 1 addition & 1 deletion ipv4/address_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
func _a(str string) Address {
addr, err := AddressFromString(str)
if err != nil {
panic("only use this is happy cases")
panic("only use this in happy cases")
}
return addr
}
Expand Down
2 changes: 1 addition & 1 deletion ipv4/mask_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestMaskLength(t *testing.T) {
func _m(length int) Mask {
m, err := MaskFromLength(length)
if err != nil {
panic("only use this is happy cases")
panic("only use this in happy cases")
}
return m
}
Expand Down
6 changes: 3 additions & 3 deletions ipv4/prefix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,23 @@ import (
func _p(cidr string) Prefix {
prefix, err := PrefixFromString(cidr)
if err != nil {
panic("only use this is happy cases")
panic("only use this in happy cases")
}
return prefix
}

func unsafePrefixFromUint32(ip uint32, length int) Prefix {
mask, err := MaskFromLength(length)
if err != nil {
panic("only use this is happy cases")
panic("only use this in happy cases")
}
return PrefixFromAddressMask(Address{ip}, mask)
}

func unsafeParseNet(prefix string) *net.IPNet {
ipNet, err := parseNet(prefix)
if err != nil {
panic("only use this is happy cases")
panic("only use this in happy cases")
}
return ipNet
}
Expand Down
2 changes: 1 addition & 1 deletion ipv4/range_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
func _r(first, last Address) Range {
r, empty := RangeFromAddresses(first, last)
if empty {
panic("only use this is non-empty cases")
panic("only use this in non-empty cases")
}
return r
}
Expand Down
10 changes: 10 additions & 0 deletions ipv4/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ func (me Set_) Remove(other SetI) {
})
}

// IsEmpty returns whether the number of IP addresses is equal to zero
func (me Set_) IsEmpty() bool {
return me.NumAddresses() == 0
}

// NumAddresses returns the number of IP addresses
func (me Set_) NumAddresses() int64 {
if me.s == nil {
Expand Down Expand Up @@ -186,6 +191,11 @@ func (me Set) Set() Set {
return me
}

// IsEmpty returns whether the number of IP addresses is equal to zero
func (me Set) IsEmpty() bool {
return me.NumAddresses() == 0
}

// NumAddresses returns the number of IP addresses
func (me Set) NumAddresses() int64 {
return me.trie.NumAddresses()
Expand Down
2 changes: 1 addition & 1 deletion ipv6/address_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
func _a(str string) Address {
addr, err := AddressFromString(str)
if err != nil {
panic("only use this is happy cases")
panic("only use this in happy cases")
}
return addr
}
Expand Down
2 changes: 1 addition & 1 deletion ipv6/mask_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func TestMaskLength(t *testing.T) {
func _m(length int) Mask {
m, err := MaskFromLength(length)
if err != nil {
panic("only use this is happy cases")
panic("only use this in happy cases")
}
return m
}
Expand Down
6 changes: 3 additions & 3 deletions ipv6/prefix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,23 @@ import (
func _p(cidr string) Prefix {
prefix, err := PrefixFromString(cidr)
if err != nil {
panic("only use this is happy cases")
panic("only use this in happy cases")
}
return prefix
}

func unsafePrefixFromUint64(high, low uint64, length int) Prefix {
mask, err := MaskFromLength(length)
if err != nil {
panic("only use this is happy cases")
panic("only use this in happy cases")
}
return PrefixFromAddressMask(Address{uint128{high, low}}, mask)
}

func unsafeParseNet(prefix string) *net.IPNet {
ipNet, err := parseNet(prefix)
if err != nil {
panic("only use this is happy cases")
panic("only use this in happy cases")
}
return ipNet
}
Expand Down
5 changes: 5 additions & 0 deletions ipv6/range.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ func (me Range) String() string {
return fmt.Sprintf("[%s,%s]", me.first, me.last)
}

// Contains returns true iff this range entirely contains the given other range
func (me Range) Contains(other SetI) bool {
return me.Set().Contains(other)
}

// Minus returns a slice of ranges resulting from subtracting the given range
// The slice will contain from 0 to 2 new ranges depending on how they overlap
func (me Range) Minus(other Range) []Range {
Expand Down
27 changes: 26 additions & 1 deletion ipv6/range_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
func _r(first, last Address) Range {
r, empty := RangeFromAddresses(first, last)
if empty {
panic("only use this is non-empty cases")
panic("only use this in non-empty cases")
}
return r
}
Expand Down Expand Up @@ -91,6 +91,31 @@ func TestRangeFirstLast(t *testing.T) {
}
}

func TestRangeContains(t *testing.T) {
tests := []struct {
description string
a, b Range
}{
{
description: "larger",
a: _p("::ffff:10.224.24.1/118").Range(),
b: _p("::ffff:10.224.26.1/120").Range(),
},
{
description: "unaligned",
a: _r(Address{ui: uint128{low: 0xffff12345678}}, Address{ui: uint128{low: 0xffff23456789}}),
b: _p("::ffff:20.224.26.1/120").Range(),
},
}
for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
assert.True(t, tt.a.Contains(tt.b))
// If they're equal then containership goes the other way too.
assert.Equal(t, tt.a == tt.b, tt.b.Contains(tt.a))
})
}
}

func TestRangeMinus(t *testing.T) {
tests := []struct {
description string
Expand Down
15 changes: 15 additions & 0 deletions ipv6/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@ func (me Set_) Set() Set {
}
}

// Build is a convenience method for making modifications to a set within a
// defined scope. It calls the given callback passing a modifiable clone of
// itself. The callback can make any changes to it. After it returns true, Build
// returns the fixed snapshot of the result.
//
// If the callback returns false, modifications are aborted and the original
// fixed table is returned.
func (me Set) Build(builder func(Set_) bool) Set {
s_ := me.Set_()
if builder(s_) {
return s_.Set()
}
return me
}

// mutate should be called by any method that modifies the set in any way
func (me Set_) mutate(mutator func() (ok bool, newNode *setNode)) {
oldNode := me.s.trie
Expand Down
10 changes: 8 additions & 2 deletions ipv6/set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,14 @@ func TestSetRemoveNil(t *testing.T) {
}

func TestFixedSetContainsPrefix(t *testing.T) {
s := NewSet_()
s.Insert(_p("2001::/64"))
s := Set{}.Build(func(s_ Set_) bool {
s_.Insert(_p("2001::/64"))
return true
})
s = s.Build(func(s_ Set_) bool {
s_.Insert(_p("2001:ffff::/64"))
return false
})
assert.True(t, s.Set().Contains(_p("2001::/112")))
assert.True(t, s.Set().Contains(_p("2001::1234:0/115")))
assert.True(t, s.Set().Contains(_p("2001:0:0:0:8000:0:0:0/65")))
Expand Down

0 comments on commit ee24ff4

Please sign in to comment.