From 616b4b71a1bba475df12f11561f4e4c9cfcdee54 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Fri, 18 Jun 2021 15:27:01 +0300 Subject: [PATCH] [#310] *: Implement string converters for enumerations Implement `String` / `FromString` method pair in all levels of enum definitions. From now `String()` returns canonical protojson-compatible values. Signed-off-by: Leonard Lyubich --- pkg/acl/eacl/enums.go | 136 +++++++++++++++++++++++++++++++++++ pkg/acl/eacl/enums_test.go | 96 +++++++++++++++++++++++++ pkg/checksum.go | 44 ++++++++++++ pkg/checksum_test.go | 42 +++++++++++ pkg/netmap/clause.go | 31 +++++--- pkg/netmap/clause_test.go | 12 ++++ pkg/netmap/helper_test.go | 36 ++++++++++ pkg/netmap/node_info.go | 29 ++++++-- pkg/netmap/node_info_test.go | 12 ++++ pkg/netmap/operation.go | 49 +++++++------ pkg/netmap/operation_test.go | 18 +++++ pkg/object/search.go | 27 +++++++ pkg/object/search_test.go | 13 ++++ pkg/object/type.go | 33 +++++++-- pkg/object/type_test.go | 65 ++++++++++++----- v2/acl/grpc/types.go | 65 +++++++++++++++++ v2/acl/string.go | 110 ++++++++++++++++++++++++++++ v2/netmap/grpc/types.go | 39 ++++++++++ v2/netmap/string.go | 68 ++++++++++++++++++ v2/object/grpc/types.go | 26 +++++++ v2/object/string.go | 66 +++++++++++------ v2/refs/grpc/types.go | 13 ++++ v2/refs/string.go | 26 +++++++ v2/session/grpc/types.go | 26 +++++++ v2/session/string.go | 47 ++++++++++++ 25 files changed, 1053 insertions(+), 76 deletions(-) create mode 100644 v2/acl/string.go create mode 100644 v2/netmap/string.go create mode 100644 v2/refs/string.go create mode 100644 v2/session/string.go diff --git a/pkg/acl/eacl/enums.go b/pkg/acl/eacl/enums.go index 19fa5b9..39a4253 100644 --- a/pkg/acl/eacl/enums.go +++ b/pkg/acl/eacl/enums.go @@ -124,6 +124,32 @@ func ActionFromV2(action v2acl.Action) (a Action) { return a } +// String returns string representation of Action. +// +// String mapping: +// * ActionAllow: ALLOW; +// * ActionDeny: DENY; +// * ActionUnknown, default: ACTION_UNSPECIFIED. +func (a Action) String() string { + return a.ToV2().String() +} + +// FromString parses Action from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (a *Action) FromString(s string) bool { + var g v2acl.Action + + ok := g.FromString(s) + + if ok { + *a = ActionFromV2(g) + } + + return ok +} + // ToV2 converts Operation to v2 Operation enum value. func (o Operation) ToV2() v2acl.Operation { switch o { @@ -170,6 +196,37 @@ func OperationFromV2(operation v2acl.Operation) (o Operation) { return o } +// String returns string representation of Operation. +// +// String mapping: +// * OperationGet: GET; +// * OperationHead: HEAD; +// * OperationPut: PUT; +// * OperationDelete: DELETE; +// * OperationSearch: SEARCH; +// * OperationRange: GETRANGE; +// * OperationRangeHash: GETRANGEHASH; +// * OperationUnknown, default: OPERATION_UNSPECIFIED. +func (o Operation) String() string { + return o.ToV2().String() +} + +// FromString parses Operation from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (o *Operation) FromString(s string) bool { + var g v2acl.Operation + + ok := g.FromString(s) + + if ok { + *o = OperationFromV2(g) + } + + return ok +} + // ToV2 converts Role to v2 Role enum value. func (r Role) ToV2() v2acl.Role { switch r { @@ -200,6 +257,33 @@ func RoleFromV2(role v2acl.Role) (r Role) { return r } +// String returns string representation of Role. +// +// String mapping: +// * RoleUser: USER; +// * RoleSystem: SYSTEM; +// * RoleOthers: OTHERS; +// * RoleUnknown, default: ROLE_UNKNOWN. +func (r Role) String() string { + return r.ToV2().String() +} + +// FromString parses Role from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (r *Role) FromString(s string) bool { + var g v2acl.Role + + ok := g.FromString(s) + + if ok { + *r = RoleFromV2(g) + } + + return ok +} + // ToV2 converts Match to v2 MatchType enum value. func (m Match) ToV2() v2acl.MatchType { switch m { @@ -226,6 +310,32 @@ func MatchFromV2(match v2acl.MatchType) (m Match) { return m } +// String returns string representation of Match. +// +// String mapping: +// * MatchStringEqual: STRING_EQUAL; +// * MatchStringNotEqual: STRING_NOT_EQUAL; +// * MatchUnknown, default: MATCH_TYPE_UNSPECIFIED. +func (m Match) String() string { + return m.ToV2().String() +} + +// FromString parses Match from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (m *Match) FromString(s string) bool { + var g v2acl.MatchType + + ok := g.FromString(s) + + if ok { + *m = MatchFromV2(g) + } + + return ok +} + // ToV2 converts FilterHeaderType to v2 HeaderType enum value. func (h FilterHeaderType) ToV2() v2acl.HeaderType { switch h { @@ -251,3 +361,29 @@ func FilterHeaderTypeFromV2(header v2acl.HeaderType) (h FilterHeaderType) { return h } + +// String returns string representation of FilterHeaderType. +// +// String mapping: +// * HeaderFromRequest: REQUEST; +// * HeaderFromObject: OBJECT; +// * HeaderTypeUnknown, default: HEADER_UNSPECIFIED. +func (h FilterHeaderType) String() string { + return h.ToV2().String() +} + +// FromString parses FilterHeaderType from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (h *FilterHeaderType) FromString(s string) bool { + var g v2acl.HeaderType + + ok := g.FromString(s) + + if ok { + *h = FilterHeaderTypeFromV2(g) + } + + return ok +} diff --git a/pkg/acl/eacl/enums_test.go b/pkg/acl/eacl/enums_test.go index 11f2224..5352849 100644 --- a/pkg/acl/eacl/enums_test.go +++ b/pkg/acl/eacl/enums_test.go @@ -115,3 +115,99 @@ func TestFilterHeaderType(t *testing.T) { require.Equal(t, eacl.FilterHeaderTypeFromV2(v2acl.HeaderTypeObject+1), eacl.HeaderTypeUnknown) }) } + +type enumIface interface { + FromString(string) bool + String() string +} + +type enumStringItem struct { + val enumIface + str string +} + +func testEnumStrings(t *testing.T, e enumIface, items []enumStringItem) { + for _, item := range items { + require.Equal(t, item.str, item.val.String()) + + s := item.val.String() + + require.True(t, e.FromString(s), s) + + require.EqualValues(t, item.val, e, item.val) + } + + // incorrect strings + for _, str := range []string{ + "some string", + "UNSPECIFIED", + } { + require.False(t, e.FromString(str)) + } +} + +func TestAction_String(t *testing.T) { + toPtr := func(v eacl.Action) *eacl.Action { + return &v + } + + testEnumStrings(t, new(eacl.Action), []enumStringItem{ + {val: toPtr(eacl.ActionAllow), str: "ALLOW"}, + {val: toPtr(eacl.ActionDeny), str: "DENY"}, + {val: toPtr(eacl.ActionUnknown), str: "ACTION_UNSPECIFIED"}, + }) +} + +func TestRole_String(t *testing.T) { + toPtr := func(v eacl.Role) *eacl.Role { + return &v + } + + testEnumStrings(t, new(eacl.Role), []enumStringItem{ + {val: toPtr(eacl.RoleUser), str: "USER"}, + {val: toPtr(eacl.RoleSystem), str: "SYSTEM"}, + {val: toPtr(eacl.RoleOthers), str: "OTHERS"}, + {val: toPtr(eacl.RoleUnknown), str: "ROLE_UNSPECIFIED"}, + }) +} + +func TestOperation_String(t *testing.T) { + toPtr := func(v eacl.Operation) *eacl.Operation { + return &v + } + + testEnumStrings(t, new(eacl.Operation), []enumStringItem{ + {val: toPtr(eacl.OperationGet), str: "GET"}, + {val: toPtr(eacl.OperationPut), str: "PUT"}, + {val: toPtr(eacl.OperationHead), str: "HEAD"}, + {val: toPtr(eacl.OperationDelete), str: "DELETE"}, + {val: toPtr(eacl.OperationSearch), str: "SEARCH"}, + {val: toPtr(eacl.OperationRange), str: "GETRANGE"}, + {val: toPtr(eacl.OperationRangeHash), str: "GETRANGEHASH"}, + {val: toPtr(eacl.OperationUnknown), str: "OPERATION_UNSPECIFIED"}, + }) +} + +func TestMatch_String(t *testing.T) { + toPtr := func(v eacl.Match) *eacl.Match { + return &v + } + + testEnumStrings(t, new(eacl.Match), []enumStringItem{ + {val: toPtr(eacl.MatchStringEqual), str: "STRING_EQUAL"}, + {val: toPtr(eacl.MatchStringNotEqual), str: "STRING_NOT_EQUAL"}, + {val: toPtr(eacl.MatchUnknown), str: "MATCH_TYPE_UNSPECIFIED"}, + }) +} + +func TestFilterHeaderType_String(t *testing.T) { + toPtr := func(v eacl.FilterHeaderType) *eacl.FilterHeaderType { + return &v + } + + testEnumStrings(t, new(eacl.FilterHeaderType), []enumStringItem{ + {val: toPtr(eacl.HeaderFromRequest), str: "REQUEST"}, + {val: toPtr(eacl.HeaderFromObject), str: "OBJECT"}, + {val: toPtr(eacl.HeaderTypeUnknown), str: "HEADER_UNSPECIFIED"}, + }) +} diff --git a/pkg/checksum.go b/pkg/checksum.go index 5d244b9..b02ae0d 100644 --- a/pkg/checksum.go +++ b/pkg/checksum.go @@ -152,3 +152,47 @@ func (c *Checksum) Parse(s string) error { return nil } + +// String returns string representation of ChecksumType. +// +// String mapping: +// * ChecksumTZ: TZ; +// * ChecksumSHA256: SHA256; +// * ChecksumUnknown, default: CHECKSUM_TYPE_UNSPECIFIED. +func (m ChecksumType) String() string { + var m2 refs.ChecksumType + + switch m { + default: + m2 = refs.UnknownChecksum + case ChecksumTZ: + m2 = refs.TillichZemor + case ChecksumSHA256: + m2 = refs.SHA256 + } + + return m2.String() +} + +// FromString parses ChecksumType from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (m *ChecksumType) FromString(s string) bool { + var g refs.ChecksumType + + ok := g.FromString(s) + + if ok { + switch g { + default: + *m = ChecksumUnknown + case refs.TillichZemor: + *m = ChecksumTZ + case refs.SHA256: + *m = ChecksumSHA256 + } + } + + return ok +} diff --git a/pkg/checksum_test.go b/pkg/checksum_test.go index e0508b8..b5a0600 100644 --- a/pkg/checksum_test.go +++ b/pkg/checksum_test.go @@ -131,3 +131,45 @@ func TestNewChecksum(t *testing.T) { require.Nil(t, chsV2.GetSum()) }) } + +type enumIface interface { + FromString(string) bool + String() string +} + +type enumStringItem struct { + val enumIface + str string +} + +func testEnumStrings(t *testing.T, e enumIface, items []enumStringItem) { + for _, item := range items { + require.Equal(t, item.str, item.val.String()) + + s := item.val.String() + + require.True(t, e.FromString(s), s) + + require.EqualValues(t, item.val, e, item.val) + } + + // incorrect strings + for _, str := range []string{ + "some string", + "undefined", + } { + require.False(t, e.FromString(str)) + } +} + +func TestChecksumType_String(t *testing.T) { + toPtr := func(v ChecksumType) *ChecksumType { + return &v + } + + testEnumStrings(t, new(ChecksumType), []enumStringItem{ + {val: toPtr(ChecksumTZ), str: "TZ"}, + {val: toPtr(ChecksumSHA256), str: "SHA256"}, + {val: toPtr(ChecksumUnknown), str: "CHECKSUM_TYPE_UNSPECIFIED"}, + }) +} diff --git a/pkg/netmap/clause.go b/pkg/netmap/clause.go index 37ea3a0..d2b5c40 100644 --- a/pkg/netmap/clause.go +++ b/pkg/netmap/clause.go @@ -42,13 +42,28 @@ func (c Clause) ToV2() netmap.Clause { } } +// String returns string representation of Clause. +// +// String mapping: +// * ClauseDistinct: DISTINCT; +// * ClauseSame: SAME; +// * ClauseUnspecified, default: CLAUSE_UNSPECIFIED. func (c Clause) String() string { - switch c { - default: - return "CLAUSE_UNSPECIFIED" - case ClauseDistinct: - return "DISTINCT" - case ClauseSame: - return "SAME" - } + return c.ToV2().String() +} + +// FromString parses Clause from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (c *Clause) FromString(s string) bool { + var g netmap.Clause + + ok := g.FromString(s) + + if ok { + *c = ClauseFromV2(g) + } + + return ok } diff --git a/pkg/netmap/clause_test.go b/pkg/netmap/clause_test.go index b30d89b..6ce5e82 100644 --- a/pkg/netmap/clause_test.go +++ b/pkg/netmap/clause_test.go @@ -29,3 +29,15 @@ func TestClauseFromV2(t *testing.T) { require.Equal(t, item.cV2, item.c.ToV2()) } } + +func TestClause_String(t *testing.T) { + toPtr := func(v Clause) *Clause { + return &v + } + + testEnumStrings(t, new(Clause), []enumStringItem{ + {val: toPtr(ClauseDistinct), str: "DISTINCT"}, + {val: toPtr(ClauseSame), str: "SAME"}, + {val: toPtr(ClauseUnspecified), str: "CLAUSE_UNSPECIFIED"}, + }) +} diff --git a/pkg/netmap/helper_test.go b/pkg/netmap/helper_test.go index 35df5b5..73b82ae 100644 --- a/pkg/netmap/helper_test.go +++ b/pkg/netmap/helper_test.go @@ -1,5 +1,11 @@ package netmap +import ( + "testing" + + "github.com/stretchr/testify/require" +) + func newFilter(name string, k, v string, op Operation, fs ...*Filter) *Filter { f := NewFilter() f.SetName(name) @@ -55,3 +61,33 @@ func getTestNode(props ...string) *Node { } return &Node{AttrMap: m} } + +type enumIface interface { + FromString(string) bool + String() string +} + +type enumStringItem struct { + val enumIface + str string +} + +func testEnumStrings(t *testing.T, e enumIface, items []enumStringItem) { + for _, item := range items { + require.Equal(t, item.str, item.val.String()) + + s := item.val.String() + + require.True(t, e.FromString(s), s) + + require.EqualValues(t, item.val, e, item.val) + } + + // incorrect strings + for _, str := range []string{ + "some string", + "undefined", + } { + require.False(t, e.FromString(str)) + } +} diff --git a/pkg/netmap/node_info.go b/pkg/netmap/node_info.go index cd81358..35f1617 100644 --- a/pkg/netmap/node_info.go +++ b/pkg/netmap/node_info.go @@ -176,15 +176,30 @@ func (s NodeState) ToV2() netmap.NodeState { } } +// String returns string representation of NodeState. +// +// String mapping: +// * NodeStateOnline: ONLINE; +// * NodeStateOffline: OFFLINE; +// * default: UNSPECIFIED. func (s NodeState) String() string { - switch s { - default: - return "STATE_UNSPECIFIED" - case NodeStateOffline: - return "OFFLINE" - case NodeStateOnline: - return "ONLINE" + return s.ToV2().String() +} + +// FromString parses NodeState from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (s *NodeState) FromString(str string) bool { + var g netmap.NodeState + + ok := g.FromString(str) + + if ok { + *s = NodeStateFromV2(g) } + + return ok } // NewNodeAttribute creates and returns new NodeAttribute instance. diff --git a/pkg/netmap/node_info_test.go b/pkg/netmap/node_info_test.go index e380561..5d09a59 100644 --- a/pkg/netmap/node_info_test.go +++ b/pkg/netmap/node_info_test.go @@ -240,3 +240,15 @@ func TestNewNodeInfo(t *testing.T) { require.EqualValues(t, netmap.UnspecifiedState, niV2.GetState()) }) } + +func TestNodeState_String(t *testing.T) { + toPtr := func(v NodeState) *NodeState { + return &v + } + + testEnumStrings(t, new(NodeState), []enumStringItem{ + {val: toPtr(NodeStateOnline), str: "ONLINE"}, + {val: toPtr(NodeStateOffline), str: "OFFLINE"}, + {val: toPtr(0), str: "UNSPECIFIED"}, + }) +} diff --git a/pkg/netmap/operation.go b/pkg/netmap/operation.go index dd388ff..af3e042 100644 --- a/pkg/netmap/operation.go +++ b/pkg/netmap/operation.go @@ -83,25 +83,34 @@ func (op Operation) ToV2() netmap.Operation { } } +// String returns string representation of Operation. +// +// String mapping: +// * OpNE: NE; +// * OpEQ: EQ; +// * OpLT: LT; +// * OpLE: LE; +// * OpGT: GT; +// * OpGE: GE; +// * OpAND: AND; +// * OpOR: OR; +// * default: OPERATION_UNSPECIFIED. func (op Operation) String() string { - switch op { - default: - return "OPERATION_UNSPECIFIED" - case OpNE: - return "NE" - case OpEQ: - return "EQ" - case OpLT: - return "LT" - case OpLE: - return "LE" - case OpGT: - return "GT" - case OpGE: - return "GE" - case OpAND: - return "AND" - case OpOR: - return "OR" - } + return op.ToV2().String() +} + +// FromString parses Operation from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (op *Operation) FromString(s string) bool { + var g netmap.Operation + + ok := g.FromString(s) + + if ok { + *op = OperationFromV2(g) + } + + return ok } diff --git a/pkg/netmap/operation_test.go b/pkg/netmap/operation_test.go index c60479b..e8b74e3 100644 --- a/pkg/netmap/operation_test.go +++ b/pkg/netmap/operation_test.go @@ -53,3 +53,21 @@ func TestOperationFromV2(t *testing.T) { require.Equal(t, item.opV2, item.op.ToV2()) } } + +func TestOperation_String(t *testing.T) { + toPtr := func(v Operation) *Operation { + return &v + } + + testEnumStrings(t, new(Operation), []enumStringItem{ + {val: toPtr(OpEQ), str: "EQ"}, + {val: toPtr(OpNE), str: "NE"}, + {val: toPtr(OpGT), str: "GT"}, + {val: toPtr(OpGE), str: "GE"}, + {val: toPtr(OpLT), str: "LT"}, + {val: toPtr(OpLE), str: "LE"}, + {val: toPtr(OpAND), str: "AND"}, + {val: toPtr(OpOR), str: "OR"}, + {val: toPtr(0), str: "OPERATION_UNSPECIFIED"}, + }) +} diff --git a/pkg/object/search.go b/pkg/object/search.go index 9622ec2..438d0aa 100644 --- a/pkg/object/search.go +++ b/pkg/object/search.go @@ -48,6 +48,33 @@ func SearchMatchFromV2(t v2object.MatchType) (m SearchMatchType) { return m } +// String returns string representation of SearchMatchType. +// +// String mapping: +// * MatchStringEqual: STRING_EQUAL; +// * MatchStringNotEqual: STRING_NOT_EQUAL; +// * MatchNotPresent: NOT_PRESENT; +// * MatchUnknown, default: MATCH_TYPE_UNSPECIFIED. +func (m SearchMatchType) String() string { + return m.ToV2().String() +} + +// FromString parses SearchMatchType from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (m *SearchMatchType) FromString(s string) bool { + var g v2object.MatchType + + ok := g.FromString(s) + + if ok { + *m = SearchMatchFromV2(g) + } + + return ok +} + type SearchFilter struct { header filterKey value fmt.Stringer diff --git a/pkg/object/search_test.go b/pkg/object/search_test.go index 62cca9b..36870bb 100644 --- a/pkg/object/search_test.go +++ b/pkg/object/search_test.go @@ -192,3 +192,16 @@ func TestSearchFiltersEncoding(t *testing.T) { require.Equal(t, fs, fs2) }) } + +func TestSearchMatchType_String(t *testing.T) { + toPtr := func(v object.SearchMatchType) *object.SearchMatchType { + return &v + } + + testEnumStrings(t, new(object.SearchMatchType), []enumStringItem{ + {val: toPtr(object.MatchStringEqual), str: "STRING_EQUAL"}, + {val: toPtr(object.MatchStringNotEqual), str: "STRING_NOT_EQUAL"}, + {val: toPtr(object.MatchNotPresent), str: "NOT_PRESENT"}, + {val: toPtr(object.MatchUnknown), str: "MATCH_TYPE_UNSPECIFIED"}, + }) +} diff --git a/pkg/object/type.go b/pkg/object/type.go index fde1aaa..82d7c00 100644 --- a/pkg/object/type.go +++ b/pkg/object/type.go @@ -34,13 +34,36 @@ func TypeFromV2(t object.Type) Type { } } +// String returns string representation of Type. +// +// String mapping: +// * TypeTombstone: TOMBSTONE; +// * TypeStorageGroup: STORAGE_GROUP; +// * TypeRegular, default: REGULAR. func (t Type) String() string { return t.ToV2().String() } -// TypeFromString parses Type from its string representation. -func TypeFromString(s string) Type { - return TypeFromV2( - object.TypeFromString(s), - ) +// FromString parses Type from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (t *Type) FromString(s string) bool { + var g object.Type + + ok := g.FromString(s) + + if ok { + *t = TypeFromV2(g) + } + + return ok +} + +// TypeFromString parses Type from its string representation. +// +// Deprecated: use FromString method. +func TypeFromString(s string) (t Type) { + t.FromString(s) + return } diff --git a/pkg/object/type_test.go b/pkg/object/type_test.go index 7ade2ef..cb8a268 100644 --- a/pkg/object/type_test.go +++ b/pkg/object/type_test.go @@ -1,28 +1,29 @@ -package object +package object_test import ( "testing" - "github.com/nspcc-dev/neofs-api-go/v2/object" + "github.com/nspcc-dev/neofs-api-go/pkg/object" + v2object "github.com/nspcc-dev/neofs-api-go/v2/object" "github.com/stretchr/testify/require" ) func TestType_ToV2(t *testing.T) { typs := []struct { - t Type - t2 object.Type + t object.Type + t2 v2object.Type }{ { - t: TypeRegular, - t2: object.TypeRegular, + t: object.TypeRegular, + t2: v2object.TypeRegular, }, { - t: TypeTombstone, - t2: object.TypeTombstone, + t: object.TypeTombstone, + t2: v2object.TypeTombstone, }, { - t: TypeStorageGroup, - t2: object.TypeStorageGroup, + t: object.TypeStorageGroup, + t2: v2object.TypeStorageGroup, }, } @@ -31,16 +32,48 @@ func TestType_ToV2(t *testing.T) { require.Equal(t, item.t2, t2) - require.Equal(t, item.t, TypeFromV2(item.t2)) + require.Equal(t, item.t, object.TypeFromV2(item.t2)) } } func TestType_String(t *testing.T) { - for _, typ := range []Type{ - TypeRegular, - TypeTombstone, - TypeStorageGroup, + toPtr := func(v object.Type) *object.Type { + return &v + } + + testEnumStrings(t, new(object.Type), []enumStringItem{ + {val: toPtr(object.TypeTombstone), str: "TOMBSTONE"}, + {val: toPtr(object.TypeStorageGroup), str: "STORAGE_GROUP"}, + {val: toPtr(object.TypeRegular), str: "REGULAR"}, + }) +} + +type enumIface interface { + FromString(string) bool + String() string +} + +type enumStringItem struct { + val enumIface + str string +} + +func testEnumStrings(t *testing.T, e enumIface, items []enumStringItem) { + for _, item := range items { + require.Equal(t, item.str, item.val.String()) + + s := item.val.String() + + require.True(t, e.FromString(s), s) + + require.EqualValues(t, item.val, e, item.val) + } + + // incorrect strings + for _, str := range []string{ + "some string", + "undefined", } { - require.Equal(t, typ, TypeFromString(typ.String())) + require.False(t, e.FromString(str)) } } diff --git a/v2/acl/grpc/types.go b/v2/acl/grpc/types.go index bfb28ed..cc9b48b 100644 --- a/v2/acl/grpc/types.go +++ b/v2/acl/grpc/types.go @@ -150,3 +150,68 @@ func (m *BearerToken_Body_TokenLifetime) SetIat(v uint64) { m.Iat = v } } + +// FromString parses Action from a string representation, +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *Action) FromString(s string) bool { + i, ok := Action_value[s] + if ok { + *x = Action(i) + } + + return ok +} + +// FromString parses Role from a string representation, +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *Role) FromString(s string) bool { + i, ok := Role_value[s] + if ok { + *x = Role(i) + } + + return ok +} + +// FromString parses Operation from a string representation, +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *Operation) FromString(s string) bool { + i, ok := Operation_value[s] + if ok { + *x = Operation(i) + } + + return ok +} + +// FromString parses MatchType from a string representation, +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *MatchType) FromString(s string) bool { + i, ok := MatchType_value[s] + if ok { + *x = MatchType(i) + } + + return ok +} + +// FromString parses HeaderType from a string representation, +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *HeaderType) FromString(s string) bool { + i, ok := HeaderType_value[s] + if ok { + *x = HeaderType(i) + } + + return ok +} diff --git a/v2/acl/string.go b/v2/acl/string.go new file mode 100644 index 0000000..1968f5d --- /dev/null +++ b/v2/acl/string.go @@ -0,0 +1,110 @@ +package acl + +import ( + acl "github.com/nspcc-dev/neofs-api-go/v2/acl/grpc" +) + +// String returns string representation of Action. +func (x Action) String() string { + return ActionToGRPCField(x).String() +} + +// FromString parses Action from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *Action) FromString(s string) bool { + var g acl.Action + + ok := g.FromString(s) + + if ok { + *x = ActionFromGRPCField(g) + } + + return ok +} + +// String returns string representation of Role. +func (x Role) String() string { + return RoleToGRPCField(x).String() +} + +// FromString parses Role from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *Role) FromString(s string) bool { + var g acl.Role + + ok := g.FromString(s) + + if ok { + *x = RoleFromGRPCField(g) + } + + return ok +} + +// String returns string representation of Operation. +func (x Operation) String() string { + return OperationToGRPCField(x).String() +} + +// FromString parses Operation from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *Operation) FromString(s string) bool { + var g acl.Operation + + ok := g.FromString(s) + + if ok { + *x = OperationFromGRPCField(g) + } + + return ok +} + +// String returns string representation of MatchType. +func (x MatchType) String() string { + return MatchTypeToGRPCField(x).String() +} + +// FromString parses MatchType from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *MatchType) FromString(s string) bool { + var g acl.MatchType + + ok := g.FromString(s) + + if ok { + *x = MatchTypeFromGRPCField(g) + } + + return ok +} + +// String returns string representation of HeaderType. +func (x HeaderType) String() string { + return HeaderTypeToGRPCField(x).String() +} + +// FromString parses HeaderType from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *HeaderType) FromString(s string) bool { + var g acl.HeaderType + + ok := g.FromString(s) + + if ok { + *x = HeaderTypeFromGRPCField(g) + } + + return ok +} diff --git a/v2/netmap/grpc/types.go b/v2/netmap/grpc/types.go index d3e2120..4340d19 100644 --- a/v2/netmap/grpc/types.go +++ b/v2/netmap/grpc/types.go @@ -174,3 +174,42 @@ func (x *NetworkInfo) SetMagicNumber(v uint64) { x.MagicNumber = v } } + +// FromString parses Clause from a string representation, +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *Clause) FromString(s string) bool { + i, ok := Clause_value[s] + if ok { + *x = Clause(i) + } + + return ok +} + +// FromString parses Operation from a string representation, +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *Operation) FromString(s string) bool { + i, ok := Operation_value[s] + if ok { + *x = Operation(i) + } + + return ok +} + +// FromString parses NodeInfo_State from a string representation, +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *NodeInfo_State) FromString(s string) bool { + i, ok := NodeInfo_State_value[s] + if ok { + *x = NodeInfo_State(i) + } + + return ok +} diff --git a/v2/netmap/string.go b/v2/netmap/string.go new file mode 100644 index 0000000..11ab18c --- /dev/null +++ b/v2/netmap/string.go @@ -0,0 +1,68 @@ +package netmap + +import ( + netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc" +) + +// String returns string representation of Clause. +func (x Clause) String() string { + return ClauseToGRPCMessage(x).String() +} + +// FromString parses Clause from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *Clause) FromString(s string) bool { + var g netmap.Clause + + ok := g.FromString(s) + + if ok { + *x = ClauseFromGRPCMessage(g) + } + + return ok +} + +// String returns string representation of Operation. +func (x Operation) String() string { + return OperationToGRPCMessage(x).String() +} + +// FromString parses Operation from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *Operation) FromString(s string) bool { + var g netmap.Operation + + ok := g.FromString(s) + + if ok { + *x = OperationFromGRPCMessage(g) + } + + return ok +} + +// String returns string representation of NodeState. +func (x NodeState) String() string { + return NodeStateToGRPCMessage(x).String() +} + +// FromString parses NodeState from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *NodeState) FromString(s string) bool { + var g netmap.NodeInfo_State + + ok := g.FromString(s) + + if ok { + *x = NodeStateFromRPCMessage(g) + } + + return ok +} diff --git a/v2/object/grpc/types.go b/v2/object/grpc/types.go index 9d86393..28eafb7 100644 --- a/v2/object/grpc/types.go +++ b/v2/object/grpc/types.go @@ -235,3 +235,29 @@ func (m *SplitInfo) SetLink(v *refs.ObjectID) { m.Link = v } } + +// FromString parses ObjectType from a string representation, +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *ObjectType) FromString(s string) bool { + i, ok := ObjectType_value[s] + if ok { + *x = ObjectType(i) + } + + return ok +} + +// FromString parses MatchType from a string representation, +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *MatchType) FromString(s string) bool { + i, ok := MatchType_value[s] + if ok { + *x = MatchType(i) + } + + return ok +} diff --git a/v2/object/string.go b/v2/object/string.go index ad82a12..3191e31 100644 --- a/v2/object/string.go +++ b/v2/object/string.go @@ -1,29 +1,55 @@ package object -const ( - typeRegularString = "Regular" - typeTombstoneString = "Tombstone" - typeStorageGroupString = "StorageGroup" +import ( + object "github.com/nspcc-dev/neofs-api-go/v2/object/grpc" ) +// String returns string representation of Type. func (t Type) String() string { - switch t { - default: - return typeRegularString - case TypeTombstone: - return typeTombstoneString - case TypeStorageGroup: - return typeStorageGroupString - } + return TypeToGRPCField(t).String() } -func TypeFromString(s string) Type { - switch s { - default: - return TypeRegular - case typeTombstoneString: - return TypeTombstone - case typeStorageGroupString: - return TypeStorageGroup +// FromString parses Type from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (t *Type) FromString(s string) bool { + var g object.ObjectType + + ok := g.FromString(s) + + if ok { + *t = TypeFromGRPCField(g) } + + return ok +} + +// TypeFromString converts string to Type. +// +// Deprecated: use FromString method. +func TypeFromString(s string) (t Type) { + t.FromString(s) + return +} + +// String returns string representation of MatchType. +func (t MatchType) String() string { + return MatchTypeToGRPCField(t).String() +} + +// FromString parses MatchType from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (t *MatchType) FromString(s string) bool { + var g object.MatchType + + ok := g.FromString(s) + + if ok { + *t = MatchTypeFromGRPCField(g) + } + + return ok } diff --git a/v2/refs/grpc/types.go b/v2/refs/grpc/types.go index b071dc8..22448e5 100644 --- a/v2/refs/grpc/types.go +++ b/v2/refs/grpc/types.go @@ -76,3 +76,16 @@ func (m *Signature) SetSign(v []byte) { m.Sign = v } } + +// FromString parses ChecksumType from a string representation, +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *ChecksumType) FromString(s string) bool { + i, ok := ChecksumType_value[s] + if ok { + *x = ChecksumType(i) + } + + return ok +} diff --git a/v2/refs/string.go b/v2/refs/string.go new file mode 100644 index 0000000..b27e07f --- /dev/null +++ b/v2/refs/string.go @@ -0,0 +1,26 @@ +package refs + +import ( + refs "github.com/nspcc-dev/neofs-api-go/v2/refs/grpc" +) + +// String returns string representation of ChecksumType. +func (t ChecksumType) String() string { + return ChecksumTypeToGRPC(t).String() +} + +// FromString parses ChecksumType from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (t *ChecksumType) FromString(s string) bool { + var g refs.ChecksumType + + ok := g.FromString(s) + + if ok { + *t = ChecksumTypeFromGRPC(g) + } + + return ok +} diff --git a/v2/session/grpc/types.go b/v2/session/grpc/types.go index 20f9ee7..cee4638 100644 --- a/v2/session/grpc/types.go +++ b/v2/session/grpc/types.go @@ -274,3 +274,29 @@ func (m *ResponseVerificationHeader) SetOrigin(v *ResponseVerificationHeader) { m.Origin = v } } + +// FromString parses ObjectSessionContext_Verb from a string representation, +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *ObjectSessionContext_Verb) FromString(s string) bool { + i, ok := ObjectSessionContext_Verb_value[s] + if ok { + *x = ObjectSessionContext_Verb(i) + } + + return ok +} + +// FromString parses ContainerSessionContext_Verb from a string representation, +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *ContainerSessionContext_Verb) FromString(s string) bool { + i, ok := ContainerSessionContext_Verb_value[s] + if ok { + *x = ContainerSessionContext_Verb(i) + } + + return ok +} diff --git a/v2/session/string.go b/v2/session/string.go new file mode 100644 index 0000000..0335ed7 --- /dev/null +++ b/v2/session/string.go @@ -0,0 +1,47 @@ +package session + +import ( + session "github.com/nspcc-dev/neofs-api-go/v2/session/grpc" +) + +// String returns string representation of ObjectSessionVerb. +func (x ObjectSessionVerb) String() string { + return ObjectSessionVerbToGRPCField(x).String() +} + +// FromString parses ObjectSessionVerb from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *ObjectSessionVerb) FromString(s string) bool { + var g session.ObjectSessionContext_Verb + + ok := g.FromString(s) + + if ok { + *x = ObjectSessionVerbFromGRPCField(g) + } + + return ok +} + +// String returns string representation of ContainerSessionVerb. +func (x ContainerSessionVerb) String() string { + return ContainerSessionVerbToGRPCField(x).String() +} + +// FromString parses ContainerSessionVerb from a string representation. +// It is a reverse action to String(). +// +// Returns true if s was parsed successfully. +func (x *ContainerSessionVerb) FromString(s string) bool { + var g session.ContainerSessionContext_Verb + + ok := g.FromString(s) + + if ok { + *x = ContainerSessionVerbFromGRPCField(g) + } + + return ok +}