forked from nspcc-dev/neofs-sdk-go
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[nspcc-dev#79] Implement type for subnet ID
Create `subnet` package. Define `ID` type of subnet identifiers. Implement encoding and support NeoFS API V2 protocol. Provide method to init instance from integer. Implement function which checks if `ID` instance refers to zero subnet.
- Loading branch information
Leonard Lyubich
committed
Nov 23, 2021
1 parent
d9317cb
commit 69644c3
Showing
5 changed files
with
203 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package subnetid | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/nspcc-dev/neofs-api-go/v2/refs" | ||
) | ||
|
||
// ID represents NeoFS subnet identifier. | ||
// | ||
// The type is compatible with the corresponding message from NeoFS API V2 protocol. | ||
// | ||
// Zero value and nil pointer is equivalent to zero subnet ID. | ||
type ID refs.SubnetID | ||
|
||
// FromV2 initializes ID from refs.SubnetID message structure. Must not be called on nil. | ||
// | ||
// Note: nil refs.SubnetID corresponds to zero ID value or nil pointer to it. | ||
func (x *ID) FromV2(msg refs.SubnetID) { | ||
*x = ID(msg) | ||
} | ||
|
||
// WriteToV2 writes ID to refs.SubnetID message structure. The message must not be nil. | ||
// | ||
// Note: nil ID corresponds to zero refs.SubnetID value or nil pointer to it. | ||
func (x ID) WriteToV2(msg *refs.SubnetID) { | ||
*msg = refs.SubnetID(x) | ||
} | ||
|
||
// Equals returns true iff both instances identify the same subnet. | ||
// | ||
// Method is NPE-safe: nil pointer equals to pointer to zero value. | ||
func (x *ID) Equals(x2 *ID) bool { | ||
return (*refs.SubnetID)(x).GetValue() == (*refs.SubnetID)(x2).GetValue() | ||
} | ||
|
||
// MarshalText encodes ID into text format according to particular NeoFS API protocol. | ||
// Supported versions: | ||
// * V2 (see refs.SubnetID type). | ||
// | ||
// Implements encoding.TextMarshaler. | ||
func (x *ID) MarshalText() ([]byte, error) { | ||
return (*refs.SubnetID)(x).MarshalText() | ||
} | ||
|
||
// UnmarshalText decodes ID from the text according to particular NeoFS API protocol. | ||
// Must not be called on nil. Supported versions: | ||
// * V2 (see refs.SubnetID type). | ||
// | ||
// Implements encoding.TextUnmarshaler. | ||
func (x *ID) UnmarshalText(text []byte) error { | ||
return (*refs.SubnetID)(x).UnmarshalText(text) | ||
} | ||
|
||
// String returns string representation of ID using MarshalText. | ||
// Returns string with message on error. | ||
// | ||
// Implements fmt.Stringer. | ||
func (x *ID) String() string { | ||
text, err := x.MarshalText() | ||
if err != nil { | ||
return fmt.Sprintf("<invalid> %v", err) | ||
} | ||
|
||
return string(text) | ||
} | ||
|
||
// Marshal encodes ID into a binary format of NeoFS API V2 protocol (Protocol Buffers with direct field order). | ||
func (x *ID) Marshal() ([]byte, error) { | ||
return (*refs.SubnetID)(x).StableMarshal(nil) | ||
} | ||
|
||
// Unmarshal decodes ID from NeoFS API V2 binary format (see Marshal). Must not be called on nil. | ||
// | ||
// Note: empty data corresponds to zero ID value or nil pointer to it. | ||
func (x *ID) Unmarshal(data []byte) error { | ||
return (*refs.SubnetID)(x).Unmarshal(data) | ||
} | ||
|
||
// SetNumber sets ID value in uint32 format. Must not be called on nil. | ||
// By default, number is 0 which refers to zero subnet. | ||
func (x *ID) SetNumber(num uint32) { | ||
(*refs.SubnetID)(x).SetValue(num) | ||
} | ||
|
||
// IsZero returns true iff the ID refers to zero subnet. | ||
func IsZero(id ID) bool { | ||
return id.Equals(nil) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package subnetid_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/nspcc-dev/neofs-api-go/v2/refs" | ||
subnetid "github.com/nspcc-dev/neofs-sdk-go/subnet/id" | ||
subnetidtest "github.com/nspcc-dev/neofs-sdk-go/subnet/id/test" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestIsZero(t *testing.T) { | ||
var id subnetid.ID | ||
|
||
require.True(t, subnetid.IsZero(id)) | ||
|
||
id.SetNumber(13) | ||
require.False(t, subnetid.IsZero(id)) | ||
|
||
id.SetNumber(0) | ||
require.True(t, subnetid.IsZero(id)) | ||
} | ||
|
||
func TestID_FromV2(t *testing.T) { | ||
const num = 13 | ||
|
||
var id1 subnetid.ID | ||
id1.SetNumber(num) | ||
|
||
var idv2 refs.SubnetID | ||
idv2.SetValue(num) | ||
|
||
var id2 subnetid.ID | ||
id2.FromV2(idv2) | ||
|
||
require.True(t, id1.Equals(&id2)) | ||
} | ||
|
||
func TestID_WriteToV2(t *testing.T) { | ||
const num = 13 | ||
|
||
var ( | ||
id subnetid.ID | ||
idv2 refs.SubnetID | ||
) | ||
|
||
id.WriteToV2(&idv2) | ||
require.Zero(t, idv2.GetValue()) | ||
|
||
id.SetNumber(num) | ||
|
||
id.WriteToV2(&idv2) | ||
require.EqualValues(t, num, idv2.GetValue()) | ||
} | ||
|
||
func TestID_Equals(t *testing.T) { | ||
const num = 13 | ||
|
||
var id1, id2, id_, id0 subnetid.ID | ||
|
||
id0.Equals(nil) | ||
|
||
id1.SetNumber(num) | ||
id2.SetNumber(num) | ||
id_.SetNumber(num + 1) | ||
|
||
require.True(t, id1.Equals(&id2)) | ||
require.False(t, id1.Equals(&id_)) | ||
require.False(t, id2.Equals(&id_)) | ||
} | ||
|
||
func TestSubnetIDEncoding(t *testing.T) { | ||
id := subnetidtest.GenerateID() | ||
|
||
t.Run("binary", func(t *testing.T) { | ||
data, err := id.Marshal() | ||
require.NoError(t, err) | ||
|
||
var id2 subnetid.ID | ||
require.NoError(t, id2.Unmarshal(data)) | ||
|
||
require.True(t, id2.Equals(id)) | ||
}) | ||
|
||
t.Run("text", func(t *testing.T) { | ||
data, err := id.MarshalText() | ||
require.NoError(t, err) | ||
|
||
var id2 subnetid.ID | ||
require.NoError(t, id2.UnmarshalText(data)) | ||
|
||
require.True(t, id2.Equals(id)) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package subnetidtest | ||
|
||
import ( | ||
"math/rand" | ||
|
||
subnetid "github.com/nspcc-dev/neofs-sdk-go/subnet/id" | ||
) | ||
|
||
// GenerateID generates and returns random subnetid.ID using math/rand.Uint32. | ||
func GenerateID() *subnetid.ID { | ||
var id subnetid.ID | ||
|
||
id.SetNumber(rand.Uint32()) | ||
|
||
return &id | ||
} |