diff --git a/pkg/object/search.go b/pkg/object/search.go new file mode 100644 index 0000000..4f7a539 --- /dev/null +++ b/pkg/object/search.go @@ -0,0 +1,96 @@ +package object + +import ( + v2object "github.com/nspcc-dev/neofs-api-go/v2/object" +) + +// SearchMatchType indicates match operation on specified header. +type SearchMatchType uint32 + +const ( + MatchUnknown SearchMatchType = iota + MatchStringEqual +) + +func (m SearchMatchType) ToV2() v2object.MatchType { + switch m { + case MatchStringEqual: + return v2object.MatchStringEqual + default: + return v2object.MatchUnknown + } +} + +func SearchMatchFromV2(t v2object.MatchType) (m SearchMatchType) { + switch t { + case v2object.MatchStringEqual: + m = MatchStringEqual + default: + m = MatchUnknown + } + + return m +} + +type SearchFilter struct { + header string + value string + op SearchMatchType +} + +type SearchFilters []SearchFilter + +func (f *SearchFilter) Header() string { + return f.header +} + +func (f *SearchFilter) Value() string { + return f.value +} + +func (f *SearchFilter) Operation() SearchMatchType { + return f.op +} + +func NewSearchFilters() SearchFilters { + return SearchFilters{} +} + +func NewSearchFiltersFromV2(v2 []v2object.SearchFilter) SearchFilters { + filters := make(SearchFilters, 0, len(v2)) + for i := range v2 { + filters = append(filters, SearchFilter{ + header: v2[i].GetName(), + value: v2[i].GetValue(), + op: SearchMatchFromV2(v2[i].GetMatchType()), + }) + } + + return filters +} + +func (f *SearchFilters) AddFilter(header, value string, op SearchMatchType) { + if *f == nil { + *f = make(SearchFilters, 0, 1) + } + + *f = append(*f, SearchFilter{ + header: header, + value: value, + op: op, + }) +} + +func (f SearchFilters) ToV2() []v2object.SearchFilter { + result := make([]v2object.SearchFilter, 0, len(f)) + for i := range f { + v2 := v2object.SearchFilter{} + v2.SetName(f[i].header) + v2.SetValue(f[i].value) + v2.SetMatchType(f[i].op.ToV2()) + + result = append(result, v2) + } + + return result +} diff --git a/pkg/object/search_test.go b/pkg/object/search_test.go new file mode 100644 index 0000000..99fb139 --- /dev/null +++ b/pkg/object/search_test.go @@ -0,0 +1,53 @@ +package object_test + +import ( + "testing" + + "github.com/nspcc-dev/neofs-api-go/pkg/object" + v2object "github.com/nspcc-dev/neofs-api-go/v2/object" + "github.com/stretchr/testify/require" +) + +var ( + eqV2Matches = map[object.SearchMatchType]v2object.MatchType{ + object.MatchUnknown: v2object.MatchUnknown, + object.MatchStringEqual: v2object.MatchStringEqual, + } +) + +func TestMatch(t *testing.T) { + t.Run("known matches", func(t *testing.T) { + for i := object.MatchUnknown; i <= object.MatchStringEqual; i++ { + require.Equal(t, eqV2Matches[i], i.ToV2()) + require.Equal(t, object.SearchMatchFromV2(i.ToV2()), i) + } + }) + + t.Run("unknown matches", func(t *testing.T) { + require.Equal(t, (object.MatchStringEqual + 1).ToV2(), v2object.MatchUnknown) + require.Equal(t, object.SearchMatchFromV2(v2object.MatchStringEqual+1), object.MatchUnknown) + }) +} + +func TestFilter(t *testing.T) { + inputs := [][]string{ + {"user-header", "user-value"}, + {object.HdrSysNameID, "objectID"}, + } + + filters := object.NewSearchFilters() + for i := range inputs { + filters.AddFilter(inputs[i][0], inputs[i][1], object.MatchStringEqual) + } + + require.Len(t, filters, len(inputs)) + for i := range inputs { + require.Equal(t, inputs[i][0], filters[i].Header()) + require.Equal(t, inputs[i][1], filters[i].Value()) + require.Equal(t, object.MatchStringEqual, filters[i].Operation()) + } + + v2 := filters.ToV2() + newFilters := object.NewSearchFiltersFromV2(v2) + require.Equal(t, filters, newFilters) +}