From 0e6e0e4678cd8abdf0a1c761739f8437d10ede59 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Thu, 18 Nov 2021 18:16:16 +0300 Subject: [PATCH] [#356] refs: Implement text encoding of `SubnetID` Implement `encoding.TextMarshaler` / `encoding.TextUnmarshaler` interfaces on `SubnetID` according to NeoFS API V2 protocol. Signed-off-by: Leonard Lyubich --- refs/types.go | 32 ++++++++++++++++++++++++++++++++ refs/types_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/refs/types.go b/refs/types.go index d8ff91a5..6e014b79 100644 --- a/refs/types.go +++ b/refs/types.go @@ -1,5 +1,10 @@ package refs +import ( + "fmt" + "strconv" +) + type OwnerID struct { val []byte } @@ -183,6 +188,33 @@ func (s *SubnetID) GetValue() uint32 { return 0 } +// MarshalText encodes SubnetID into text format according to NeoFS API V2 protocol: +// value in base-10 integer string format. +// +// Implements encoding.TextMarshaler. +func (s *SubnetID) MarshalText() ([]byte, error) { + num := s.GetValue() // NPE safe, returns zero on nil (zero subnet) + + return []byte(strconv.FormatUint(uint64(num), 10)), nil +} + +// UnmarshalText decodes SubnetID from the text according to NeoFS API V2 protocol: +// should be base-10 integer string format. +// +// Must not be called on nil. +// +// Implements encoding.TextUnmarshaler. +func (s *SubnetID) UnmarshalText(txt []byte) error { + num, err := strconv.ParseUint(string(txt), 10, 32) + if err != nil { + return fmt.Errorf("invalid numeric value: %w", err) + } + + s.value = uint32(num) + + return nil +} + // IsZeroSubnet returns true iff the SubnetID refers to zero subnet. func IsZeroSubnet(id *SubnetID) bool { return id.GetValue() == 0 diff --git a/refs/types_test.go b/refs/types_test.go index a1c68cd0..187a8432 100644 --- a/refs/types_test.go +++ b/refs/types_test.go @@ -1,6 +1,7 @@ package refs_test import ( + "strconv" "testing" "github.com/nspcc-dev/neofs-api-go/v2/refs" @@ -18,3 +19,32 @@ func TestZeroSubnet(t *testing.T) { refs.MakeZeroSubnet(id) require.True(t, refs.IsZeroSubnet(id)) } + +func TestSubnetID_MarshalText(t *testing.T) { + var id refs.SubnetID + + const val = 15 + + id.SetValue(val) + + txt, err := id.MarshalText() + require.NoError(t, err) + + res, err := strconv.ParseUint(string(txt), 10, 32) + require.NoError(t, err) + + require.EqualValues(t, val, res) +} + +func TestSubnetID_UnmarshalText(t *testing.T) { + const val = 15 + + str := strconv.FormatUint(val, 10) + + var id refs.SubnetID + + err := id.UnmarshalText([]byte(str)) + require.NoError(t, err) + + require.EqualValues(t, val, id.GetValue()) +}