func ProhibitFields(requested []string, search ...string) error {
	for _, s := range search {
		if HasAnyField(requested, s) {
			return errProhibitedField.WithAttributes("field", s)
		}
	}
	return nil
}
ProhibitFields returns nil if the given requested paths contain none of the given fields and error otherwise.
The requested fields (i.e. `a.b`) may be of a higher level than the search path (i.e. `a.b.c`).
package ttnpb
import (
	"strings"
	"go.thethings.network/lorawan-stack/v3/pkg/errors"
)
func TopLevelFields(paths []string) []string {
	seen := make(map[string]struct{}, len(paths))
	out := make([]string, 0, len(paths))
	for _, path := range paths {
		parts := strings.SplitN(path, ".", 2)
		if _, ok := seen[parts[0]]; ok {
			continue
		}
		seen[parts[0]] = struct{}{}
		out = append(out, parts[0])
	}
	return out
}
func BottomLevelFields(paths []string) []string {
	seen := make(map[string]struct{}, len(paths))
	for _, path := range paths {
		prefix := path
		if i := strings.LastIndex(prefix, "."); i >= 0 {
			prefix = prefix[:i]
		}
		if _, ok := seen[prefix]; ok {
			delete(seen, prefix)
		}
		seen[path] = struct{}{}
	}
	out := make([]string, 0, len(seen))
	for k := range seen {
		out = append(out, k)
	}
	return out
}
func HasOnlyAllowedFields(requested []string, allowed ...string) bool {
nextRequested:
	for _, requested := range requested {
		for _, allowed := range allowed {
			if requested == allowed || strings.HasPrefix(requested, allowed+".") {
				continue nextRequested
			}
		}
		return false
	}
	return true
}
func HasAnyField(requested []string, search ...string) bool {
	for _, requested := range requested {
		for _, search := range search {
			if requested == search || strings.HasPrefix(search, requested+".") {
				return true
			}
		}
	}
	return false
}
func FlattenPaths(paths, flatten []string) []string {
	res := make([]string, 0, len(paths))
	flattened := make(map[string]bool)
	for _, path := range paths {
		for _, flatten := range flatten {
			if flatten == path || strings.HasPrefix(path, flatten+".") {
				if !flattened[flatten] {
					res = append(res, flatten)
					flattened[flatten] = true
				}
			} else {
				res = append(res, path)
			}
		}
	}
	return res
}
var errMissingField = errors.Define("missing_field", "field `{field}` is missing")
func RequireFields(requested []string, search ...string) error {
	for _, s := range search {
		if !HasAnyField(requested, s) {
			return errMissingField.WithAttributes("field", s)
		}
	}
	return nil
}
var errProhibitedField = errors.Define("prohibited_field", "field `{field}` is prohibited")