mirror of
https://github.com/logos-messaging/go-multiaddr.git
synced 2026-01-02 13:03:11 +00:00
shortcut split on components
Instead of re-parsing single-components, shortcut split/for-each functions.
This commit is contained in:
parent
dda950c1d3
commit
877fe6538c
26
util.go
26
util.go
@ -4,6 +4,9 @@ import "fmt"
|
||||
|
||||
// Split returns the sub-address portions of a multiaddr.
|
||||
func Split(m Multiaddr) []Multiaddr {
|
||||
if _, ok := m.(*Component); ok {
|
||||
return []Multiaddr{m}
|
||||
}
|
||||
var addrs []Multiaddr
|
||||
ForEach(m, func(c Component) bool {
|
||||
addrs = append(addrs, &c)
|
||||
@ -58,6 +61,11 @@ func StringCast(s string) Multiaddr {
|
||||
|
||||
// SplitFirst returns the first component and the rest of the multiaddr.
|
||||
func SplitFirst(m Multiaddr) (*Component, Multiaddr) {
|
||||
// Shortcut if we already have a component
|
||||
if c, ok := m.(*Component); ok {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
b := m.Bytes()
|
||||
if len(b) == 0 {
|
||||
return nil, nil
|
||||
@ -74,6 +82,11 @@ func SplitFirst(m Multiaddr) (*Component, Multiaddr) {
|
||||
|
||||
// SplitLast returns the rest of the multiaddr and the last component.
|
||||
func SplitLast(m Multiaddr) (Multiaddr, *Component) {
|
||||
// Shortcut if we already have a component
|
||||
if c, ok := m.(*Component); ok {
|
||||
return nil, c
|
||||
}
|
||||
|
||||
b := m.Bytes()
|
||||
if len(b) == 0 {
|
||||
return nil, nil
|
||||
@ -106,6 +119,13 @@ func SplitLast(m Multiaddr) (Multiaddr, *Component) {
|
||||
// component on which the callback first returns will be included in the
|
||||
// *second* multiaddr.
|
||||
func SplitFunc(m Multiaddr, cb func(Component) bool) (Multiaddr, Multiaddr) {
|
||||
// Shortcut if we already have a component
|
||||
if c, ok := m.(*Component); ok {
|
||||
if cb(*c) {
|
||||
return nil, m
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
b := m.Bytes()
|
||||
if len(b) == 0 {
|
||||
return nil, nil
|
||||
@ -140,6 +160,12 @@ func SplitFunc(m Multiaddr, cb func(Component) bool) (Multiaddr, Multiaddr) {
|
||||
//
|
||||
// This function iterates over components *by value* to avoid allocating.
|
||||
func ForEach(m Multiaddr, cb func(c Component) bool) {
|
||||
// Shortcut if we already have a component
|
||||
if c, ok := m.(*Component); ok {
|
||||
cb(*c)
|
||||
return
|
||||
}
|
||||
|
||||
b := m.Bytes()
|
||||
for len(b) > 0 {
|
||||
n, c, err := readComponent(b)
|
||||
|
||||
42
util_test.go
42
util_test.go
@ -60,6 +60,48 @@ func TestSplitFirstLast(t *testing.T) {
|
||||
t.Errorf("expected %s to be %s", rest, restExp)
|
||||
}
|
||||
}
|
||||
|
||||
c, err := NewComponent("ip4", "127.0.0.1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ci, m := SplitFirst(c)
|
||||
if !ci.Equal(c) || m != nil {
|
||||
t.Error("split first on component failed")
|
||||
}
|
||||
m, ci = SplitLast(c)
|
||||
if !ci.Equal(c) || m != nil {
|
||||
t.Error("split last on component failed")
|
||||
}
|
||||
cis := Split(c)
|
||||
if len(cis) != 1 || !cis[0].Equal(c) {
|
||||
t.Error("split on component failed")
|
||||
}
|
||||
m1, m2 := SplitFunc(c, func(c Component) bool {
|
||||
return true
|
||||
})
|
||||
if m1 != nil || !m2.Equal(c) {
|
||||
t.Error("split func(true) on component failed")
|
||||
}
|
||||
m1, m2 = SplitFunc(c, func(c Component) bool {
|
||||
return false
|
||||
})
|
||||
if !m1.Equal(c) || m2 != nil {
|
||||
t.Error("split func(false) on component failed")
|
||||
}
|
||||
|
||||
i := 0
|
||||
ForEach(c, func(ci Component) bool {
|
||||
if i != 0 {
|
||||
t.Error("expected exactly one component")
|
||||
}
|
||||
i++
|
||||
if !ci.Equal(c) {
|
||||
t.Error("foreach on component failed")
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func TestSplitFunc(t *testing.T) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user