Documentation
¶
Overview ¶
Package nomix provides a set of types and functions for handling tags and metadata in a generic way.
Index ¶
- Constants
- Variables
- func CreateFloat64(val any) (float64, error)
- func CreateFloat64Slice(val any) ([]float64, error)
- func CreateInt64(val any) (int64, error)
- func CreateInt64Slice(val any) ([]int64, error)
- func CreateTime(val any, opts Options) (time.Time, error)
- func CreateTimeSlice(val any, opts Options) ([]time.Time, error)
- func GetMetaValue[T any](set MetaSet, name string) (T, error)
- func GetTag[T any](set TagSet, name string) (T, error)
- func GetTagValue[T any](set TagSet, name string) (T, error)
- func ParseTime(val string, opts Options) (time.Time, error)
- func WithLocString(opts *Options)
- func WithRadixHEX(opts *Options)
- type AllGetter
- type Comparer
- type CreateFunc
- type Creator
- type Definition
- type Kind
- type MetaAllGetter
- type MetaAllSetter
- type MetaAppender
- type MetaFromGetter
- type MetaSet
- type Metadata
- type NamedCreator
- type NamedParser
- type Option
- type Options
- type ParseFunc
- type Parser
- type Registry
- type Single
- func (tag *Single[T]) Get() T
- func (tag *Single[T]) Set(v T)
- func (tag *Single[T]) String() string
- func (tag *Single[T]) TagEqual(other Tag) bool
- func (tag *Single[T]) TagKind() Kind
- func (tag *Single[T]) TagName() string
- func (tag *Single[T]) TagSame(other Tag) bool
- func (tag *Single[T]) TagSet(v any) error
- func (tag *Single[T]) TagValue() any
- func (tag *Single[T]) ValidateWith(rule verax.Rule) error
- func (tag *Single[T]) Value() (driver.Value, error)
- type Slice
- func (tag *Slice[T]) Get() []T
- func (tag *Slice[T]) Set(v []T)
- func (tag *Slice[T]) String() string
- func (tag *Slice[T]) TagEqual(other Tag) bool
- func (tag *Slice[T]) TagKind() Kind
- func (tag *Slice[T]) TagName() string
- func (tag *Slice[T]) TagSame(other Tag) bool
- func (tag *Slice[T]) TagSet(v any) error
- func (tag *Slice[T]) TagValue() any
- func (tag *Slice[T]) ValidateWith(rule verax.Rule) error
- func (tag *Slice[T]) Value() (driver.Value, error)
- type Spec
- type Tag
- type TagSet
- type Tagger
- type ValueComparer
Examples ¶
Constants ¶
const ( KindBool = 0b00000001_00000000 | KindInt64 KindInt = 0b00000010_00000000 | KindInt64 )
Derived Tag kinds. Derived kinds are types that are derived from base kinds.
const ( KindByteSlice = 0b00000000_00000001 | KindSlice KindStringSlice = KindString | KindSlice KindInt64Slice = KindInt64 | KindSlice KindFloat64Slice = KindFloat64 | KindSlice KindTimeSlice = KindTime | KindSlice KindUUIDSlice = KindUUID | KindSlice KindBoolSlice = KindBool | KindSlice KindIntSlice = KindInt | KindSlice )
Multi value (slice) Tag kinds.
Variables ¶
var ( // ErrInvType represents an invalid element type. ErrInvType = errors.New("invalid element type") // ErrInvFormat represents an invalid element format. ErrInvFormat = errors.New("invalid element format") // ErrMissing represents a missing set element. ErrMissing = errors.New("missing element") // ErrInvValue represents an invalid element value. ErrInvValue = errors.New("invalid element value") // ErrNoCreator represents a missing tag creator for a type. ErrNoCreator = errors.New("creator not found") // ErrNoSpec represents a missing tag spec for a type. ErrNoSpec = errors.New("spec not found") // ErrNotImpl represents a missing method implementation or // functionality for a type. ErrNotImpl = errors.New("not implemented") )
Metadata parsing and casting errors.
Functions ¶
func CreateFloat64 ¶ added in v0.2.0
CreateFloat64 casts the value to float64. Returns the float64 and nil error if the value is a byte, int, int8, int16, int32, int64, float32, or float64. Returns 0.0 and ErrInvType if the value's type is not a supported numeric type.
NOTE: For values outside ±2^53 range, the function will return an error.
func CreateFloat64Slice ¶ added in v0.2.0
CreateFloat64Slice casts the value to []float64. Returns the slice and nil error if the value is a []int, []int8, []int16, []int32, []int64, []float32, or []float64. Returns nil and ErrInvType if the value's type is not a supported numeric slice type.
NOTE: For values outside ±2^53 range, the function will return an error.
func CreateInt64 ¶ added in v0.2.0
CreateInt64 casts the value to int64. Returns the int64 and nil error if the value is a byte, int, int8, int16, int32, or int64. Returns 0 and ErrInvType if the value is not a supported integer type.
func CreateInt64Slice ¶ added in v0.2.0
CreateInt64Slice casts the value to []int64. Returns the []int64 and nil error if the value is a []int, []int8, []int16, []int32, or []int64. Returns nil and ErrInvType if the value's type is not a supported numeric slice type.
func CreateTime ¶ added in v0.2.0
CreateTime casts the value to time.Time or when the value is a string parses it in the given location but only when the format is provided. Returns the time and nil error on success. Returns zero value time and error if the value's type is not a supported type or the value is not a valid time representation.
func CreateTimeSlice ¶ added in v0.2.0
CreateTimeSlice casts the value to []time.Time, or when the value is a []string, it parses its elements in the given location but only when the format is provided. With the "zvt" argument you may provide a list of strings representing zero value time. Returns the []time.Time and nil error on success. Returns nil and error if the value's type is not a supported type or the value is not a valid time representation.
func GetMetaValue ¶ added in v0.5.0
GetMetaValue retrieves the value of type T from the set. Returns the value if found, or the zero value for T and error.
func GetTag ¶ added in v0.5.0
GetTag retrieves the Tag of type T from the set. Returns the Tag if found, or the zero value for T and error.
func GetTagValue ¶ added in v0.5.0
GetTagValue retrieves the value of the Tag of type T from the set. Returns the value if found, or the zero value for T ane error.
func ParseTime ¶
ParseTime parses a string representation of time.Time. Returns the time and nil error if the value is a valid time representation. Returns zero value time and ErrInvFormat if the value is not a valid time representation.
func WithLocString ¶
func WithLocString(opts *Options)
WithLocString is the MetaSet option allowing string timezone names.
func WithRadixHEX ¶ added in v0.5.0
func WithRadixHEX(opts *Options)
WithRadixHEX sets base to hexadecimal when parsing integers.
Types ¶
type AllGetter ¶ added in v0.5.0
type AllGetter interface {
// TagGetAll returns all tags in the set as a map. May return nil. The
// returned map should be treated as read-only.
TagGetAll() map[string]Tag
}
AllGetter is an interface for retrieving all tags in the set.
type Comparer ¶ added in v0.5.0
type Comparer interface {
// TagSame returns true if both tags have the same name, kind and value.
TagSame(other Tag) bool
}
Comparer is an interface for comparing tags.
type CreateFunc ¶ added in v0.2.0
CreateFunc function signature for creating Tag instances.
Example ¶
package main
import (
"database/sql/driver"
"fmt"
"strconv"
"github.com/ctx42/nomix/pkg/nomix"
)
func main() {
type Int = nomix.Single[int]
// CreateInt is a function creating a new [Int] instance by casting
// argument "val" to int.
var CreateInt = func(name string, val any, opts ...nomix.Option) (*Int, error) {
if v, ok := val.(int); ok {
sqlValue := func(val int) (driver.Value, error) {
return int64(val), nil
}
return nomix.NewSingle(name, v, nomix.KindInt, strconv.Itoa, sqlValue), nil
}
return nil, nomix.ErrInvType
}
var tcf nomix.CreateFunc
tcf = nomix.TagCreateFunc(CreateInt)
tag, err := tcf("A", 42)
format := "name: %s; kind: %s; value: %v; err: %v\n"
fmt.Printf(format, tag.TagName(), tag.TagKind(), tag.TagValue(), err)
}
Output: name: A; kind: KindInt; value: 42; err: <nil>
func TagCreateFunc ¶ added in v0.2.0
TagCreateFunc creates a CreateFunc from a function that creates concrete tag instances.
Examples:
TagCreateFunc(func(name string, val any, opts ...Option) (MyTag, error))
type Creator ¶ added in v0.5.0
type Creator interface {
// TagCreate creates the appropriate [Tag] instance based on the value's
// type. It returns the [ErrNoCreator] error if the value's type is not
// supported. The name must be set by the implementer.
TagCreate(value any, opts ...Option) (Tag, error)
}
Creator is an interface for creating Tag instances.
type Definition ¶ added in v0.2.0
type Definition struct {
// contains filtered or unexported fields
}
Definition represents a named tag definition. In other words, it wraps a Spec and a tag name.
func Define ¶ added in v0.2.0
func Define(name string, spec Spec, rules ...verax.Rule) *Definition
Define defines named Tag.
Example ¶
package main
import (
"fmt"
"github.com/ctx42/verax/pkg/verax"
"github.com/ctx42/nomix/pkg/nomix"
"github.com/ctx42/nomix/pkg/xtag"
)
func main() {
def := nomix.Define("name", xtag.IntSpec(), verax.Max(42))
tag, err := def.TagCreate(42)
fmt.Printf("- success: %s err: %v\n", tag, err)
tag, err = def.TagCreate(44)
fmt.Printf("- failure: %v err: %v\n", tag, err)
}
Output: - success: 42 err: <nil> - failure: <nil> err: name: must be no greater than 42
func (*Definition) TagCreate ¶ added in v0.2.0
func (def *Definition) TagCreate(val any, opts ...Option) (Tag, error)
TagCreate creates a new Tag matching the definition. It does not validate the value.
func (*Definition) TagKind ¶ added in v0.2.0
func (def *Definition) TagKind() Kind
TagKind returns the tag definition kind.
func (*Definition) TagName ¶ added in v0.2.0
func (def *Definition) TagName() string
TagName returns the tag name definition is for.
type Kind ¶ added in v0.5.0
type Kind int16
Kind describes the type of Tag value.
const ( KindString Kind = 0b00000000_00000010 KindInt64 Kind = 0b00000000_00000100 KindFloat64 Kind = 0b00000000_00001000 KindTime Kind = 0b00000000_00010000 KindJSON Kind = 0b00000000_00100000 KindUUID Kind = 0b00000000_01000000 )
Base Tag kinds.
const KindSlice Kind = 0b00000000_10000000
KindSlice is a Kind type modifier indicating it is a slice.
type MetaAllGetter ¶
type MetaAllGetter interface {
// MetaGetAll returns all tags in the set as a map. May return nil. The
// returned map should be treated as read-only.
MetaGetAll() map[string]any
}
MetaAllGetter is an interface wrapping MetaGetAll method.
type MetaAllSetter ¶
type MetaAllSetter interface {
// MetaSetAll sets metadata on the implementor. If the value with the given
// name already exists in the set, it will be overwritten. The nil values
// must be ignored.
MetaSetAll(map[string]any)
}
MetaAllSetter is an interface wrapping MetaSetAll method.
type MetaAppender ¶
type MetaAppender interface {
// MetaAppend appends all implementor metadata to the passed map.
MetaAppend(map[string]any)
}
MetaAppender is an interface wrapping MetaAppend method.
type MetaFromGetter ¶
type MetaFromGetter interface {
// MetaSetFrom sets metadata on the implementor from the [MetaAllGetter].
MetaSetFrom(src MetaAllGetter)
}
MetaFromGetter is an interface wrapping MetaFromGetter method.
type MetaSet ¶
type MetaSet struct {
// contains filtered or unexported fields
}
MetaSet represents a set of metadata key-values.
Example ¶
package main
import (
"fmt"
"github.com/ctx42/nomix/pkg/nomix"
)
func main() {
set := nomix.NewMetaSet()
set.MetaSet("A", 42)
set.MetaSet("B", true)
set.MetaSet("C", "foo")
fmt.Printf("There are %d entries in the set:\n", set.MetaCount())
fmt.Printf("- A: %v\n", set.MetaGet("A"))
fmt.Printf("- B: %v\n", set.MetaGet("B"))
fmt.Printf("- C: %v\n", set.MetaGet("C"))
fmt.Printf("- D: %v\n", set.MetaGet("D"))
}
Output: There are 3 entries in the set: - A: 42 - B: true - C: foo - D: <nil>
func NewMetaSet ¶
NewMetaSet returns a new MetaSet instance. By default, the new map is initialized with the length equal to 10.
func (MetaSet) MetaDelete ¶
func (MetaSet) MetaDeleteAll ¶
func (set MetaSet) MetaDeleteAll()
MetaDeleteAll deletes all metadata from the set.
func (MetaSet) MetaGetAll ¶
type Metadata ¶
type Metadata interface {
// MetaGet retrieves from the set a metadata value by its name. If the name
// does not exist in the set, it returns nil.
MetaGet(name string) any
// MetaSet adds a named value to the set. If the value with the given name
// already exists in the set, it will be overwritten. Setting a nil value
// must be implemented as a no-op.
MetaSet(name string, value any)
// MetaDelete removes from the set the metadata value by name. If the name
// does not exist, the method has no effect.
MetaDelete(name string)
}
Metadata is an interface for managing a collection of distinctly named metadata values. The implementations must not allow for nil values to be stored in the set.
type NamedCreator ¶ added in v0.5.0
type NamedCreator interface {
// TagCreate creates the appropriate [Tag] instance based on the value's
// type. It returns the [ErrNoCreator] error if the value's type is not
// supported.
TagCreate(name string, value any, opts ...Option) (Tag, error)
}
NamedCreator is an interface for creating named Tag instances.
type NamedParser ¶ added in v0.5.0
NamedParser is an interface for creating named Tag instances from their string representation. The name must be set by the implementer.
type Option ¶
type Option func(*Options)
Option represents an option function.
func WithMeta ¶
WithMeta is an option to set the initial map for the MetaSet.
The caller must not use the passed map after the call to this option. The MetaSet becomes its new owner.
func WithTags ¶
WithTags is an option to set the initial map for the TagSet.
The caller must not use the passed map after the call to this option. The TagSet becomes its new owner.
func WithTimeFormat ¶
WithTimeFormat is the MetaSet option setting string time format.
func WithTimeLoc ¶
WithTimeLoc is the MetaSet option setting location for parsed time strings.
func WithZeroTime ¶
WithZeroTime is MetaSet option setting zero time values.
type Options ¶
type Options struct {
// Initial map size.
//
// Used by [NewTagSet] and [NewMetaSet] to allocate the init map.
Length int
// Time format.
//
// When set, [MetaSet.MetaGetTime] will allow time to be represented as a
// string.
TimeFormat string
// Location to parse format.
//
// When set [time.ParseInLocation] instead of [time.Parse] in the
// [MetaSet.MetaGetTime] to parse strings.
Location *time.Location
// When set [MetaSet.MetaGetLoc] will allow timezone to be represented as a
// sting.
//
// Example:
// Europe/Warsaw
LocationAsString bool
// The base for integers when parsing.
Radix int
// contains filtered or unexported fields
}
Options represent a set of options used by MetaSet and TagSet.
func NewOptions ¶ added in v0.5.0
NewOptions returns a new Options instance with default values.
type ParseFunc ¶ added in v0.2.0
ParseFunc function signature for creating Tag instances from their string representation.
func TagParseFunc ¶ added in v0.2.0
TagParseFunc creates a ParseFunc from a function that creates concrete tag instances from their string representation.
Examples:
TagParseFunc(func(name string, val string, opts ...Option) (T, error))
type Parser ¶ added in v0.5.0
Parser is an interface for creating Tag instances from their string representation.
type Registry ¶ added in v0.2.0
type Registry struct {
// contains filtered or unexported fields
}
Registry represents a collection of [Spec]s.
Example ¶
package main
import (
"fmt"
"github.com/ctx42/nomix/pkg/nomix"
"github.com/ctx42/nomix/pkg/xtag"
)
func main() {
reg := nomix.NewRegistry()
_ = reg.Register(xtag.IntSpec()) // Register spec.
_, _ = reg.Associate(0, nomix.KindInt) // Associate the int type with spec.
spec := reg.SpecForKind(nomix.KindInt) // Get spec for KindInt.
tag, err := spec.TagCreate("A", 42)
format := "name: %s; kind: %s; value: %v; err: %v\n"
fmt.Printf(format, tag.TagName(), tag.TagKind(), tag.TagValue(), err)
spec = reg.SpecForType(0) // Get spec for int type.
tag, err = spec.TagCreate("B", 44)
fmt.Printf(format, tag.TagName(), tag.TagKind(), tag.TagValue(), err)
// Convenience function to create tags for registered types.
tag, err = reg.Create("C", 11)
fmt.Printf(format, tag.TagName(), tag.TagKind(), tag.TagValue(), err)
}
Output: name: A; kind: KindInt; value: 42; err: <nil> name: B; kind: KindInt; value: 44; err: <nil> name: C; kind: KindInt; value: 11; err: <nil>
func GlobalRegistry ¶ added in v0.5.0
func GlobalRegistry() *Registry
GlobalRegistry returns the global Registry instance.
func NewRegistry ¶ added in v0.2.0
func NewRegistry() *Registry
NewRegistry returns a new Registry instance.
func (*Registry) Associate ¶ added in v0.5.0
Associate links a Go type to the given Kind, overwriting any existing association. Returns the previous kind association or Kind(0) if none. Returns an error if no Spec is registered for the kind.
func (*Registry) Create ¶ added in v0.2.0
Create creates a new Tag for the given value. The value's type must be registered.
func (*Registry) Register ¶ added in v0.2.0
Register registers a Spec for the given Kind. Returns nil if successful, or an error if the kind is already registered. Each kind can have only one spec. Must be called before associating Go types with a Spec.
func (*Registry) SpecForKind ¶ added in v0.5.0
SpecForKind retrieves the Spec for the given Kind. Use Spec.IsZero to check if a spec exists for the kind.
func (*Registry) SpecForType ¶ added in v0.5.0
SpecForType retrieves the Spec for the given type. Requires prior type association with a Spec. Use Spec.IsZero to check if a spec is available for the type.
type Single ¶ added in v0.5.0
type Single[T comparable] struct { // contains filtered or unexported fields }
Single is a generic type for single value Tag.
func NewSingle ¶ added in v0.5.0
func NewSingle[T comparable]( name string, val T, kind Kind, strValuer func(T) string, sqlValuer func(T) (driver.Value, error), ) *Single[T]
NewSingle returns a new instance of Single.
func (*Single[T]) ValidateWith ¶ added in v0.5.0
type Slice ¶ added in v0.5.0
type Slice[T comparable] struct { // contains filtered or unexported fields }
Slice is a generic type for multi value Tag.
func NewSlice ¶ added in v0.5.0
func NewSlice[T comparable]( name string, val []T, kind Kind, strValuer func([]T) string, sqlValuer func([]T) (driver.Value, error), ) *Slice[T]
NewSlice returns a new instance of Slice.
func (*Slice[T]) ValidateWith ¶ added in v0.5.0
type Spec ¶ added in v0.5.0
type Spec struct {
// contains filtered or unexported fields
}
Spec is a specification for a tag kind.
func NewSpec ¶ added in v0.5.0
func NewSpec(knd Kind, tcr CreateFunc, tpr ParseFunc) Spec
NewSpec creates a new Spec instance.
Example ¶
package main
import (
"fmt"
"github.com/ctx42/nomix/pkg/nomix"
"github.com/ctx42/nomix/pkg/xtag"
)
func main() {
spec := nomix.NewSpec(
nomix.KindInt,
nomix.TagCreateFunc(xtag.CreateInt),
nomix.TagParseFunc(xtag.ParseInt),
)
tagA, errA := spec.TagCreate("A", 42)
tagB, errB := spec.TagParse("B", "42")
fmt.Printf("- A: %v err: %v\n", tagA.TagValue(), errA)
fmt.Printf("- B: %v err: %v\n", tagB.TagValue(), errB)
}
Output: - A: 42 err: <nil> - B: 42 err: <nil>
type Tag ¶
type Tag interface {
// TagName returns tag name.
TagName() string
// TagKind returns the [Kind] holding the information about the type of
// the tag value. Use it to interpret the value returned by the
// [Tag.TagValue] method.
TagKind() Kind
// TagValue returns tag value.
// You may use the value returned by the [Tag.Kind] method
// to cast it to the proper type.
TagValue() any
}
Tag is an interface representing a tag.
Tags are named and typed values that can be used to annotate objects.
type TagSet ¶
type TagSet struct {
// contains filtered or unexported fields
}
TagSet represents a set of tags.
Example ¶
package main
import (
"fmt"
"github.com/ctx42/nomix/pkg/nomix"
"github.com/ctx42/nomix/pkg/xtag"
)
func main() {
set := nomix.NewTagSet()
set.TagSet(
xtag.NewInt("A", 42),
xtag.NewBool("B", true),
xtag.NewString("C", "foo"),
)
fmt.Printf("There are %d tags in the set:\n", set.TagCount())
fmt.Printf("- A: %v\n", set.TagGet("A").TagValue())
fmt.Printf("- B: %v\n", set.TagGet("B").TagValue())
fmt.Printf("- C: %v\n", set.TagGet("C").TagValue())
fmt.Printf("- D: %v\n", set.TagGet("D"))
}
Output: There are 3 tags in the set: - A: 42 - B: true - C: foo - D: <nil>
func (TagSet) MetaGetAll ¶
func (TagSet) TagDeleteAll ¶
func (set TagSet) TagDeleteAll()
TagDeleteAll deletes all tags from the set.
type Tagger ¶
type Tagger interface {
// TagGet retrieves from the set a [Tag] by its name. If the name doesn't
// exist in the set, it returns nil.
TagGet(name string) Tag
// TagSet adds instances of [Tag] to the set. If the tag name already
// exists in the set, it will be overwritten. The nil instances are ignored.
TagSet(tag ...Tag)
// TagDelete removes from the set the [Tag] by name. If the name does not
// exist, the method has no effect.
TagDelete(name string)
}
Tagger is an interface for managing a collection of distinctly named Tag instances (set). The implementations must not allow for nil values to be stored in the set.
type ValueComparer ¶ added in v0.5.0
type ValueComparer interface {
// TagEqual returns true if both tags are having the same kind and value.
TagEqual(other Tag) bool
}
ValueComparer is an interface for comparing tag values.