Add address clone and compare helpers

This commit is contained in:
Virgil 2026-04-02 01:54:41 +00:00
parent ebe9036dfa
commit fa38cb9d74
2 changed files with 94 additions and 0 deletions

View file

@ -102,4 +102,32 @@ func TestAddressHelpers(t *testing.T) {
t.Fatalf("%s: IsValid() = %v, want %v", tc.name, got, tc.isValid)
}
}
left := Address{Version: 0, Hash: []byte{1, 2, 3}}
right := left.Clone()
if !left.Equals(right) {
t.Fatal("Clone() should produce an equal address")
}
if got := left.Compare(right); got != 0 {
t.Fatalf("Compare() = %d, want 0", got)
}
if got := (Address{Version: 0, Hash: []byte{1, 2, 3}}).Compare(Address{Version: 1, Hash: []byte{1, 2, 3}}); got >= 0 {
t.Fatalf("Compare() = %d, want negative", got)
}
if got := (Address{Version: 1, Hash: []byte{1, 2, 3}}).Compare(Address{Version: 0, Hash: []byte{1, 2, 3}}); got <= 0 {
t.Fatalf("Compare() = %d, want positive", got)
}
var injected Address
if got := injected.Inject(left); got != &injected {
t.Fatal("Inject() should return the receiver")
}
if !injected.Equals(left) {
t.Fatal("Inject() should copy the source address")
}
}

View file

@ -37,6 +37,72 @@ type Address struct {
Hash []byte
}
// Inject copies another address into this one.
func (a *Address) Inject(other Address) *Address {
a.Version = other.Version
a.Hash = other.Hash
return a
}
// Clone returns a shallow copy of the address.
func (a Address) Clone() Address {
var clone Address
return *clone.Inject(a)
}
// Equals reports whether two addresses have the same version and hash.
func (a Address) Equals(other Address) bool {
if a.Version != other.Version {
return false
}
if len(a.Hash) != len(other.Hash) {
return false
}
for i := range a.Hash {
if a.Hash[i] != other.Hash[i] {
return false
}
}
return true
}
// Compare orders two addresses by version and then by hash bytes.
func (a Address) Compare(other Address) int {
if a.Version < other.Version {
return -1
}
if a.Version > other.Version {
return 1
}
min := len(a.Hash)
if len(other.Hash) < min {
min = len(other.Hash)
}
for i := 0; i < min; i++ {
if a.Hash[i] < other.Hash[i] {
return -1
}
if a.Hash[i] > other.Hash[i] {
return 1
}
}
switch {
case len(a.Hash) < len(other.Hash):
return -1
case len(a.Hash) > len(other.Hash):
return 1
default:
return 0
}
}
// IsNull reports whether the address hash is entirely zero bytes.
func (a Address) IsNull() bool {
for _, b := range a.Hash {