Package capabilities
import "github.com/ornew/hff/capabilities"
Generated from this checkout's Go source. Released versions are also on pkg.go.dev.
Overview
Package capabilities defines which HFF features a service permits at compile time. It controls semantics, not the grammar: every engine parses the same syntax and rejects a disabled operation during Compile.
Start with Standard for all built-in features, or None for an explicitly empty policy. Derive a policy with Allow and Without; these return new immutable sets rather than changing their receiver. The zero Set means unspecified and is rejected by engine.New.
Operator IDs control operations such as Arithmetic and RegexOperators. Method("string.contains") and Method("list.contains") are separate permissions even though both use contains in a query. Group IDs, such as Regex and StructuralEquality, select related IDs together. IDs returns concrete enabled IDs in sorted order, not the group aliases used to construct the set.
Dependencies are checked rather than silently enabled. For example, allowing list.any also requires Callbacks; allowing NestedCallbacks requires Callbacks. Check validates a built-in policy. CheckWithMethods also recognizes declared extension IDs; engine.New performs the corresponding check with its methods.
Permission does not imply backend implementation support. Compile checks the service policy; a later backend Build may still reject an operation it cannot translate faithfully. Use backend profiles to inspect support separately.
Index
Types
type ID
type ID string
ID is a stable permission identifier used by an explicit capability Set. IDs describe compile-time HFF features; they do not authorize service operations or provide backend implementations.
const (
// Logical permits Boolean query composition and truth evaluation.
Logical ID = "operator:logical"
// Comparison permits value and null comparisons.
Comparison ID = "operator:comparison"
// Arithmetic permits arithmetic operators.
Arithmetic ID = "operator:arithmetic"
// Access permits field access.
Access ID = "access:field"
// Index permits list and map indexing.
Index ID = "access:index"
// Guard permits postfix no-value guards.
Guard ID = "access:guard"
// TypeGuard permits runtime type narrowing.
TypeGuard ID = "access:type-guard"
// Collections permits list and object literals.
Collections ID = "literal:collection"
// Callbacks permits callback expressions.
Callbacks ID = "expression:callback"
// NestedCallbacks permits nested callbacks and requires Callbacks.
NestedCallbacks ID = "expression:nested-callback"
// ListEquality permits structural list comparisons.
ListEquality ID = "comparison:list-equality"
// ObjectEquality permits structural object comparisons.
ObjectEquality ID = "comparison:object-equality"
// StructuralEquality is a group alias for both structural equality IDs.
StructuralEquality ID = "group:structural-equality"
// Regex is a group alias for RegexOperators and string.matches.
Regex ID = "group:regex"
// RegexOperators permits regex match operators.
RegexOperators ID = "operator:regex"
)
func Method
func Method(name string) ID
Method identifies a built-in method or declared extension, for example Method("string.matches") or Method("service.lookup.v1"). For an extension, pass the declaration's ID suffix (without the "method:" prefix), then both declare it in the Engine and explicitly Allow this ID. This grants permission only; a backend implementation must be registered separately.
type Set
type Set struct {
// contains filtered or unexported fields
}
Set is an immutable capability policy. Its zero value means unspecified; select None or Standard (or derive a policy with Allow and Without) before passing it to engine.New. For example, start with Standard().Without(Regex) to remove both regex operators and string.matches. Set is a compile-time permission policy, not a backend implementation or service authorization policy.
func None
func None() Set
None returns an explicitly empty policy. It differs from the zero Set, which is unspecified and rejected by engine.New. Add only the permissions a restricted engine should compile:
policy := capabilities.None().Allow(capabilities.Logical, capabilities.Access) engine.New(engine.WithSchema(schemaType), engine.WithCapabilities(policy))
func Standard
func Standard() Set
Standard returns the built-in policy, including structural equality and built-in methods. It does not enable extension IDs; each extension needs an explicit Allow(Method(id)) and a matching Engine declaration. It is a permission preset, not a claim that every backend implements every feature.
func (Set) Allow
func (s Set) Allow(ids ...ID) Set
Allow returns a new Set with the requested IDs enabled; s is unchanged. StructuralEquality expands to ListEquality and ObjectEquality, and Regex expands to RegexOperators and string.matches. Dependencies are not added implicitly: for example, NestedCallbacks requires Callbacks, so enable both before Check:
policy := capabilities.None().Allow(capabilities.Callbacks, capabilities.NestedCallbacks)
Example
{
policy := capabilities.None().Allow(
capabilities.Logical, capabilities.Comparison, capabilities.Access,
capabilities.Callbacks, capabilities.Method("list.any"),
)
fmt.Println("valid:", policy.Check() == nil)
fmt.Println("list.any:", policy.Has(capabilities.Method("list.any")))
fmt.Println("list.all:", policy.Has(capabilities.Method("list.all")))
}
Complete runnable example
package main
import (
"fmt"
"github.com/ornew/hff/capabilities"
)
func main() {
policy := capabilities.None().Allow(
capabilities.Logical, capabilities.Comparison, capabilities.Access,
capabilities.Callbacks, capabilities.Method("list.any"),
)
fmt.Println("valid:", policy.Check() == nil)
fmt.Println("list.any:", policy.Has(capabilities.Method("list.any")))
fmt.Println("list.all:", policy.Has(capabilities.Method("list.all")))
}
Output:
valid: true list.any: true list.all: false
func (Set) Check
func (s Set) Check() error
Check validates that the Set is specified, all selected and removed IDs are known built-in permissions, and enabled permissions have their dependencies. It never enables missing permissions. Use CheckWithMethods when the policy selects or removes declared extension IDs.
Example
{
policy := capabilities.Standard().Without(capabilities.Callbacks)
fmt.Println("dependency error:", policy.Check() != nil)
}
Complete runnable example
package main
import (
"fmt"
"github.com/ornew/hff/capabilities"
)
func main() {
// Removing a dependency does not silently remove its dependent methods.
policy := capabilities.Standard().Without(capabilities.Callbacks)
fmt.Println("dependency error:", policy.Check() != nil)
}
Output:
dependency error: true
func (Set) CheckWithMethods
func (s Set) CheckWithMethods(methodIDs ...string) error
CheckWithMethods validates the Set while treating methodIDs as known extension declaration IDs. It does not add permissions: an enabled capabilities.Method(id) is still required. Removed extension IDs also require their declaration ID in methodIDs. Unknown IDs, an unspecified Set, or missing dependencies return an error. engine.New wraps policy errors in an HFF ConfigurationError when validating Engine options.
Example
{
extension := capabilities.Method("service.lookup.v1")
policy := capabilities.None().Without(extension)
fmt.Println(policy.Check() != nil)
fmt.Println(policy.CheckWithMethods("service.lookup.v1") == nil)
fmt.Println(policy.Has(extension))
}
Complete runnable example
package main
import (
"fmt"
"github.com/ornew/hff/capabilities"
)
func main() {
extension := capabilities.Method("service.lookup.v1")
policy := capabilities.None().Without(extension)
fmt.Println(policy.Check() != nil) // The referenced extension is unknown here.
fmt.Println(policy.CheckWithMethods("service.lookup.v1") == nil)
fmt.Println(policy.Has(extension)) // A known declaration does not grant permission.
}
Output:
true true false
func (Set) Has
func (s Set) Has(id ID) bool
Has reports whether id is enabled. For a group alias, it returns true only when every expanded member ID is enabled. The zero Set therefore reports false for every permission.
func (Set) IDs
func (s Set) IDs() []ID
IDs returns a defensive copy of enabled member IDs in lexical order. Group aliases are expanded, so the result lists their constituent IDs.
func (Set) Specified
func (s Set) Specified() bool
Specified reports whether a policy was explicitly selected rather than left at the zero value. None is specified even though it contains no IDs.
func (Set) Without
func (s Set) Without(ids ...ID) Set
Without returns a new Set with the requested IDs removed; s is unchanged. Removing a group alias removes every member. Removing a dependency while leaving a dependent permission can make Check fail. IDs supplied to Without must be known even when they are not enabled; Check reports unknown IDs.
Example
{
standard := capabilities.Standard()
policy := standard.Without(capabilities.Regex, capabilities.StructuralEquality)
fmt.Println("regex enabled:", policy.Has(capabilities.RegexOperators))
fmt.Println("string contains enabled:", policy.Has(capabilities.Method("string.contains")))
fmt.Println("original unchanged:", standard.Has(capabilities.Regex))
fmt.Println("policy valid:", policy.Check() == nil)
}
Complete runnable example
package main
import (
"fmt"
"github.com/ornew/hff/capabilities"
)
func main() {
standard := capabilities.Standard()
policy := standard.Without(capabilities.Regex, capabilities.StructuralEquality)
fmt.Println("regex enabled:", policy.Has(capabilities.RegexOperators))
fmt.Println("string contains enabled:", policy.Has(capabilities.Method("string.contains")))
fmt.Println("original unchanged:", standard.Has(capabilities.Regex))
fmt.Println("policy valid:", policy.Check() == nil)
}
Output:
regex enabled: false string contains enabled: true original unchanged: true policy valid: true