go_subnetter/netsplit/funcs_structuredresults.go

75 lines
1.5 KiB
Go

package netsplit
import (
"net/netip"
"go4.org/netipx"
)
/*
GetSplitter returns the first (should be *only*) non-nill NetSplitter on a StructuredResults.
If none is found, splitter will be nil but no panic/error will occur.
*/
func (s *StructuredResults) GetSplitter() (splitter NetSplitter) {
if s == nil || s.Splitter == nil {
return
}
/*
TODO(?): It'd be nice if I could just reflect .Interface() this
to a NetSplitter but I think I'd then have to typeswitch
into the real type regardless, which is lame.
*/
if s.Splitter.CIDR != nil {
splitter = s.Splitter.CIDR
} else if s.Splitter.Host != nil {
splitter = s.Splitter.Host
} else if s.Splitter.Subnet != nil {
splitter = s.Splitter.Subnet
} else if s.Splitter.VLSM != nil {
splitter = s.Splitter.VLSM
}
return
}
/*
Uncontain returns a set of values that "unstructure" a StructuredResults.
(Essentially the opposite procedure of Contain().)
*/
func (s *StructuredResults) Uncontain() (origPfx *netip.Prefix, nets []*netip.Prefix, remaining *netipx.IPSet, splitter NetSplitter, err error) {
var ipsb *netipx.IPSetBuilder
if s == nil {
return
}
origPfx = s.Original
if s.Allocated != nil {
nets = make([]*netip.Prefix, len(s.Allocated))
for idx, i := range s.Allocated {
nets[idx] = i.Network
}
}
if s.Unallocated != nil {
ipsb = new(netipx.IPSetBuilder)
for _, i := range s.Unallocated {
if i.Network != nil {
ipsb.AddPrefix(*i.Network)
}
}
if remaining, err = ipsb.IPSet(); err != nil {
return
}
}
splitter = s.GetSplitter()
return
}