func (f *Filter) InnerFilters() []*Filter {
	return filtersFromV2(
		(*netmap.Filter)(f).
			GetFilters(),
	)
}
InnerFilters returns list of inner filters.
package netmap
import (
	"fmt"
	"strconv"
	"github.com/nspcc-dev/neofs-api-go/v2/netmap"
)
type Filter netmap.Filter
const MainFilterName = "*"
func (c *Context) applyFilter(name string, b *Node) bool {
	return name == MainFilterName || c.match(c.Filters[name], b)
}
func (c *Context) processFilters(p *PlacementPolicy) error {
	for _, f := range p.Filters() {
		if err := c.processFilter(f, true); err != nil {
			return err
		}
	}
	return nil
}
func (c *Context) processFilter(f *Filter, top bool) error {
	if f == nil {
		return fmt.Errorf("%w: FILTER", ErrMissingField)
	}
	if f.Name() == MainFilterName {
		return fmt.Errorf("%w: '*' is reserved", ErrInvalidFilterName)
	}
	if top && f.Name() == "" {
		return ErrUnnamedTopFilter
	}
	if !top && f.Name() != "" && c.Filters[f.Name()] == nil {
		return fmt.Errorf("%w: '%s'", ErrFilterNotFound, f.Name())
	}
	switch f.Operation() {
	case OpAND, OpOR:
		for _, flt := range f.InnerFilters() {
			if err := c.processFilter(flt, false); err != nil {
				return err
			}
		}
	default:
		if len(f.InnerFilters()) != 0 {
			return ErrNonEmptyFilters
		} else if !top && f.Name() != "" {  
			return nil
		}
		switch f.Operation() {
		case OpEQ, OpNE:
		case OpGT, OpGE, OpLT, OpLE:
			n, err := strconv.ParseUint(f.Value(), 10, 64)
			if err != nil {
				return fmt.Errorf("%w: '%s'", ErrInvalidNumber, f.Value())
			}
			c.numCache[f] = n
		default:
			return fmt.Errorf("%w: %s", ErrInvalidFilterOp, f.Operation())
		}
	}
	if top {
		c.Filters[f.Name()] = f
	}
	return nil
}
func (c *Context) match(f *Filter, b *Node) bool {
	switch f.Operation() {
	case OpAND, OpOR:
		for _, lf := range f.InnerFilters() {
			if lf.Name() != "" {
				lf = c.Filters[lf.Name()]
			}
			ok := c.match(lf, b)
			if ok == (f.Operation() == OpOR) {
				return ok
			}
		}
		return f.Operation() == OpAND
	default:
		return c.matchKeyValue(f, b)
	}
}
func (c *Context) matchKeyValue(f *Filter, b *Node) bool {
	switch f.Operation() {
	case OpEQ:
		return b.Attribute(f.Key()) == f.Value()
	case OpNE:
		return b.Attribute(f.Key()) != f.Value()
	default:
		var attr uint64
		switch f.Key() {
		case AttrPrice:
			attr = b.Price
		case AttrCapacity:
			attr = b.Capacity
		default:
			var err error
			attr, err = strconv.ParseUint(b.Attribute(f.Key()), 10, 64)
			if err != nil {
				return false
			}
		}
		switch f.Operation() {
		case OpGT:
			return attr > c.numCache[f]
		case OpGE:
			return attr >= c.numCache[f]
		case OpLT:
			return attr < c.numCache[f]
		case OpLE:
			return attr <= c.numCache[f]
		default:
		}
	}
	return false
}
func NewFilter() *Filter {
	return NewFilterFromV2(new(netmap.Filter))
}
func NewFilterFromV2(f *netmap.Filter) *Filter {
	return (*Filter)(f)
}
func (f *Filter) ToV2() *netmap.Filter {
	return (*netmap.Filter)(f)
}
func (f *Filter) Key() string {
	return (*netmap.Filter)(f).
		GetKey()
}
func (f *Filter) SetKey(key string) {
	(*netmap.Filter)(f).
		SetKey(key)
}
func (f *Filter) Value() string {
	return (*netmap.Filter)(f).
		GetValue()
}
func (f *Filter) SetValue(val string) {
	(*netmap.Filter)(f).
		SetValue(val)
}
func (f *Filter) Name() string {
	return (*netmap.Filter)(f).
		GetName()
}
func (f *Filter) SetName(name string) {
	(*netmap.Filter)(f).
		SetName(name)
}
func (f *Filter) Operation() Operation {
	return OperationFromV2(
		(*netmap.Filter)(f).
			GetOp(),
	)
}
func (f *Filter) SetOperation(op Operation) {
	(*netmap.Filter)(f).
		SetOp(op.ToV2())
}
func filtersFromV2(fs []*netmap.Filter) []*Filter {
	if fs == nil {
		return nil
	}
	res := make([]*Filter, 0, len(fs))
	for i := range fs {
		res = append(res, NewFilterFromV2(fs[i]))
	}
	return res
}