[#79] Implement type for subnet information

Create `subnet` package. Define `Info` type of the subnet info. Support
encoding and transport over the NeoFS API V2 protocol. Add methods to
work with identifier and owner.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2021-11-23 21:20:12 +03:00 committed by LeL
parent 755c01264e
commit 8175462050
2 changed files with 171 additions and 0 deletions

92
subnet/subnet.go Normal file
View file

@ -0,0 +1,92 @@
package subnet
import (
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-api-go/v2/subnet"
"github.com/nspcc-dev/neofs-sdk-go/owner"
subnetid "github.com/nspcc-dev/neofs-sdk-go/subnet/id"
)
// Info represents information about NeoFS subnet.
//
// The type is compatible with the corresponding message from NeoFS API V2 protocol.
//
// Zero value and nil pointer to it represents zero subnet w/o an owner.
type Info subnet.Info
// FromV2 initializes Info from subnet.Info message structure. Must not be called on nil.
func (x *Info) FromV2(msg subnet.Info) {
*x = Info(msg)
}
// WriteToV2 writes Info to subnet.Info message structure. The message must not be nil.
func (x Info) WriteToV2(msg *subnet.Info) {
*msg = subnet.Info(x)
}
// Marshal encodes Info into a binary format of NeoFS API V2 protocol (Protocol Buffers with direct field order).
func (x *Info) Marshal() ([]byte, error) {
return (*subnet.Info)(x).StableMarshal(nil)
}
// Unmarshal decodes Info from NeoFS API V2 binary format (see Marshal). Must not be called on nil.
//
// Note: empty data corresponds to zero Info value or nil pointer to it.
func (x *Info) Unmarshal(data []byte) error {
return (*subnet.Info)(x).Unmarshal(data)
}
// SetID sets the identifier of the subnet that Info describes.
func (x *Info) SetID(id subnetid.ID) {
infov2 := (*subnet.Info)(x)
idv2 := infov2.ID()
if idv2 == nil {
idv2 = new(refs.SubnetID)
infov2.SetID(idv2)
}
id.WriteToV2(idv2)
}
// ReadID reads the identifier of the subnet that Info describes. Arg must not be nil.
func (x Info) ReadID(id *subnetid.ID) {
infov2 := (subnet.Info)(x)
idv2 := infov2.ID()
if idv2 == nil {
subnetid.MakeZero(id)
return
}
id.FromV2(*idv2)
}
// SetOwner sets subnet owner ID.
func (x *Info) SetOwner(id owner.ID) {
infov2 := (*subnet.Info)(x)
idv2 := infov2.Owner()
if idv2 == nil {
idv2 = new(refs.OwnerID)
infov2.SetOwner(idv2)
}
// FIXME: we need to implement and use owner.ID.WriteToV2() method
*idv2 = *id.ToV2()
}
// HasOwner checks if subnet owner is set.
func (x Info) HasOwner() bool {
return (*subnet.Info)(&x).Owner() != nil
}
// ReadOwner reads the identifier of the subnet that Info describes.
// Must be called only if owner is set (see HasOwner). Arg must not be nil.
func (x Info) ReadOwner(id *owner.ID) {
infov2 := (subnet.Info)(x)
// FIXME: we need to implement and use owner.ID.FromV2 method
id2 := owner.NewIDFromV2(infov2.Owner())
*id = *id2
}

79
subnet/subnet_test.go Normal file
View file

@ -0,0 +1,79 @@
package subnet_test
import (
"testing"
subnetv2 "github.com/nspcc-dev/neofs-api-go/v2/subnet"
subnettest "github.com/nspcc-dev/neofs-api-go/v2/subnet/test"
"github.com/nspcc-dev/neofs-sdk-go/owner"
ownertest "github.com/nspcc-dev/neofs-sdk-go/owner/test"
"github.com/nspcc-dev/neofs-sdk-go/subnet"
subnetid "github.com/nspcc-dev/neofs-sdk-go/subnet/id"
"github.com/stretchr/testify/require"
)
func TestInfoZero(t *testing.T) {
var info subnet.Info
var id subnetid.ID
info.ReadID(&id)
require.True(t, subnetid.IsZero(id))
require.False(t, info.HasOwner())
}
func TestInfo_SetID(t *testing.T) {
var (
idFrom, idTo subnetid.ID
info subnet.Info
)
idFrom.SetNumber(222)
info.SetID(idFrom)
info.ReadID(&idTo)
require.True(t, idTo.Equals(&idFrom))
}
func TestInfo_SetOwner(t *testing.T) {
var (
idFrom, idTo owner.ID
info subnet.Info
)
idFrom = *ownertest.GenerateID()
require.False(t, info.HasOwner())
info.SetOwner(idFrom)
require.True(t, info.HasOwner())
info.ReadOwner(&idTo)
require.True(t, idTo.Equal(&idFrom))
}
func TestInfo_WriteToV2(t *testing.T) {
var (
infoTo, infoFrom subnet.Info
infoV2From, infoV2To subnetv2.Info
)
infoV2From = *subnettest.GenerateSubnetInfo(false)
infoFrom.FromV2(infoV2From)
infoFrom.WriteToV2(&infoV2To)
infoTo.FromV2(infoV2To)
require.Equal(t, infoV2From, infoV2To)
require.Equal(t, infoFrom, infoTo)
}