Documentation
¶
Overview ¶
Package tag expands JaWS tag values into comparable keys that identify elements during dirtying, broadcasts and event routing.
TagExpand rejects expanded key values that cannot be matched reliably as tags, including values whose static type is comparable but whose runtime contents are not, and otherwise admissible values containing NaN that do not equal themselves.
Index ¶
- Variables
- func FindTagGetter(x any) (path string, tgType reflect.Type, found bool)
- func MustTagExpand(ctx Context, tag any) []any
- func NewErrNotComparable(x any) error
- func NewErrNotUsableAsTag(x any) error
- func TagExpand(ctx Context, tag any) (result []any, err error)
- func TagString(tag any) string
- type Context
- type Tag
- type TagGetter
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrIllegalTagType errIllegalTagType
ErrIllegalTagType is returned when a UI tag type is disallowed.
var ErrNotComparable errNotComparable
ErrNotComparable is returned when a UI object or tag is not comparable.
var ErrNotUsableAsTag errNotUsableAsTag
ErrNotUsableAsTag is returned when a value cannot be used as a tag.
A tag key must be comparable at runtime and equal to itself so later dirtying, broadcasts and event routing can match it reliably. This error also matches ErrNotComparable via errors.Is.
var ErrTooManyTags errTooManyTags
ErrTooManyTags is returned when tag expansion exceeds the recursion depth (maxTagDepth) or result count (maxTagCount) limits.
Functions ¶
func FindTagGetter ¶
FindTagGetter searches x recursively for a nested TagGetter.
The search is bounded: it follows at most maxTagDepth levels of nesting and scans only the first maxHintScan elements of any array or slice. It is used only to enrich the ErrNotUsableAsTag diagnostic, so these bounds trade completeness for a cheap, terminating search.
It is a best-effort diagnostic aid: the maxHintScan and maxTagDepth bounds may change, and a negative result is not authoritative, so callers should not rely on it for non-diagnostic purposes.
func MustTagExpand ¶
MustTagExpand calls TagExpand and either logs or panics if expansion fails.
On a non-nil ctx, expansion errors are passed to Context.MustLog (which logs them, or panics if no Logger is set); MustTagExpand then returns the partial result from TagExpand. A nil ctx always panics on error.
func NewErrNotComparable ¶
NewErrNotComparable returns ErrNotComparable if x is not comparable.
func NewErrNotUsableAsTag ¶
NewErrNotUsableAsTag returns ErrNotUsableAsTag for an unusable tag key.
It returns nil for nil and for values that are comparable at runtime and equal to themselves. It only validates key usability; it does not apply TagExpand's tag-type policy, so a value may pass this check and still be rejected with ErrIllegalTagType.
func TagExpand ¶
TagExpand expands tag into a flat list of unique, usable tag keys.
tag may be nil, a Tag, a slice of tags, a TagGetter or another value that is comparable at runtime and equals itself. The predeclared string, bool, signed integer, unsigned integer other than uintptr, and floating-point types are rejected with ErrIllegalTagType, as are template.HTML, template.HTMLAttr, jid.Jid and key.Key. This catches common accidental tags. An expanded key value that is not comparable at runtime or does not equal itself is rejected with ErrNotUsableAsTag (which also matches ErrNotComparable via errors.Is). Expansion that exceeds the nesting-depth or total-count limits is rejected with ErrTooManyTags.
On error, result contains the tags expanded before the failure. If an expanded value is not usable as a tag key, result is nil and err matches ErrNotUsableAsTag.
Expansion reads tag and any values returned by TagGetter.JawsGetTag by reference, so tag and those values must not be mutated concurrently with the call.
Example (ErrorsIs) ¶
package main
import (
"errors"
"fmt"
"github.com/linkdata/jaws/lib/tag"
)
func main() {
_, err := tag.TagExpand(nil, []int{1})
fmt.Println(errors.Is(err, tag.ErrNotUsableAsTag))
fmt.Println(errors.Is(err, tag.ErrNotComparable))
}
Output: true true
Example (TagGetter) ¶
package main
import (
"fmt"
"github.com/linkdata/jaws/lib/tag"
)
type exampleItem struct {
Name string
}
func (item *exampleItem) JawsGetTag(tag.Context) any {
return item
}
func main() {
item := &exampleItem{Name: "row"}
tags, err := tag.TagExpand(nil, []any{item, tag.Tag("list")})
if err != nil {
panic(err)
}
fmt.Println(len(tags), tags[0] == item, tags[1] == tag.Tag("list"))
}
Output: 2 true true
Types ¶
type Context ¶
type Context interface {
// Initial returns the Request's initial HTTP request, or nil.
Initial() (r *http.Request)
// Get returns the JaWS session value for the key, or nil.
Get(key string) any
// Set sets the JaWS session value for the key.
Set(key string, value any)
// Context returns the Request's context.
Context() (ctx context.Context)
// Log sends an error to the Logger set in the Jaws.
// Has no effect if the err is nil or the Logger is nil.
// Returns err.
Log(err error) error
// MustLog sends an error to the Logger set in the Jaws or
// panics with the given error if no Logger is set.
// Has no effect if the err is nil.
MustLog(err error)
}
Context is the request state made available while expanding tags.
type TagGetter ¶
type TagGetter interface {
// JawsGetTag returns the dynamic tag or tags for the implementing object.
//
// ctx may be nil — [TagExpand] is routinely called with a nil [Context] — so
// implementations must not dereference it unconditionally.
JawsGetTag(ctx Context) any
}
TagGetter exposes dynamic tags during TagExpand.