diff --git a/netipx.go b/netipx.go index 08d57db..57e8146 100644 --- a/netipx.go +++ b/netipx.go @@ -546,32 +546,24 @@ func appendRangePrefixes(dst []netip.Prefix, makePrefix prefixMaker, a, b uint12 return dst } -// CompareAddr returns -1 if a.Less(b), 1 if b.Less(0), else it -// returns 0. -func CompareAddr(a, b netip.Addr) int { - if a.Less(b) { - return -1 - } - if b.Less(a) { - return 1 - } - return 0 -} - -// ComparePrefix -1 if a.Addr().Less(b), 1 if -// b.Addr().Less(0), else if a and b have the same address, it -// compares their prefix bit length, returning -1, 0, or 1. +// ComparePrefix is a compare function (returning -1, 0 or 1) +// sorting prefixes first by address family (IPv4 before IPv6), +// then by prefix length (smaller prefixes first), then by +// address. func ComparePrefix(a, b netip.Prefix) int { aa, ba := a.Addr(), b.Addr() - if aa == ba { - ab, bb := a.Bits(), b.Bits() - if ab < bb { + if al, bl := aa.BitLen(), ba.BitLen(); al != bl { + if al < bl { return -1 } - if bb < ab { - return 1 + return 1 + } + ab, bb := a.Bits(), b.Bits() + if ab != bb { + if ab < bb { + return -1 } - return 0 + return 1 } - return CompareAddr(a.Addr(), b.Addr()) + return aa.Compare(ba) } diff --git a/netipx_test.go b/netipx_test.go index 1384333..f33805c 100644 --- a/netipx_test.go +++ b/netipx_test.go @@ -872,33 +872,23 @@ func TestNoAllocs(t *testing.T) { }) } -func TestCompareAddr(t *testing.T) { - tests := []struct { - a, b string - want int - }{ - {"1.1.1.1", "1.1.1.2", -1}, - {"1.1.1.2", "1.1.1.1", 1}, - {"1.1.1.1", "1.1.1.1", 0}, - {"1.1.1.1", "1::1", -1}, - } - for _, tt := range tests { - if got := CompareAddr(netip.MustParseAddr(tt.a), netip.MustParseAddr(tt.b)); got != tt.want { - t.Errorf("f(%q, %q) = %v; want %v", tt.a, tt.b, got, tt.want) - } - } -} - func TestComparePrefix(t *testing.T) { tests := []struct { a, b string want int }{ - {"1.1.1.1/10", "1.1.1.2/10", -1}, - {"1.1.1.2/10", "1.1.1.1/10", 1}, - {"1.1.1.1/10", "1.1.1.1/10", 0}, - {"1.1.1.1/9", "1.1.1.1/10", -1}, - {"1.1.1.1/32", "1::1/128", -1}, + // sort by address family + {"1.0.0.0/8", "1::/8", -1}, + {"1::/8", "1.0.0.0/8", 1}, + + // then sort by bitlen + {"1.0.0.0/7", "1.0.0.0/8", -1}, + {"1.0.0.0/8", "1.0.0.0/7", 1}, + {"1.0.0.0/8", "1.0.0.0/8", 0}, + + // then sort by addr + {"1.0.0.0/8", "1.0.0.1/8", -1}, + {"1.0.0.1/8", "1.0.0.0/8", 1}, } for _, tt := range tests { if got := ComparePrefix(netip.MustParsePrefix(tt.a), netip.MustParsePrefix(tt.b)); got != tt.want {