feature

package module
v0.8.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2025 License: MIT Imports: 8 Imported by: 0

README

feature Go Reference Lint Test

Package feature implements a simple abstraction for feature flags with arbitrary values.

Examples

Registering a flag

A flag is registered on a FlagSet.

Flags are created using a specific method based on the type of the value of the flag, named after the type.

Currently, the supported methods are

Each method will return a callback that takes a context.Context and returns a value of the specific type.

There is also feature.Typed and feature.TypedFunc which can be used to register flags using an arbitrary, generic type. Note that you can not currently override typed values for a context in a safe way.

For example:

package main

import (
	"context"

	"github.com/nussjustin/feature"
)

func main() {
	var set feature.FlagSet

	myFeature := set.Bool("my-feature", "some new feature", false)

	if myFeature(context.Background()) {
		println("my-feature enabled") // never runs, see next section
	}
}

It is also possible to register a flag with a callback that is used to determine the flag value dynamically:

package main

import (
	"context"

	"github.com/nussjustin/feature"
)

func main() {
	var set feature.FlagSet

	myFeature := set.BoolFunc("my-feature", "some new feature", func(ctx context.Context) bool {
		// ... do something with ctx ...
		return false
	})

	if myFeature(context.Background()) {
		println("my-feature enabled") // never runs, see next section
	}
}
Context-specific values

By default, the values returned for each flag will be the default value specified when creating the flag.

The FlagSet.Context method can be used to set custom values for feature flags on a per-context basis.

Example:

package main

import (
	"context"

	"github.com/nussjustin/feature"
)

func main() {
	var set feature.FlagSet

	myFeature := set.Bool("my-feature", "some new feature", false)

	// Enable the feature for our context
	ctx := set.Context(context.Background(),
		feature.BoolValue("my-feature", true))
	
	if myFeature(ctx) {
		println("my-feature enabled")
	}
}

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

License

MIT

Documentation

Overview

Package feature implements a simple abstraction for feature flags with dynamic values.

Index

Constants

This section is empty.

Variables

View Source
var ErrDuplicateFlag = errors.New("duplicate flag")

ErrDuplicateFlag is thrown by methods like FlagSet.Bool if a flag with a given name is already registered.

Functions

func Typed added in v0.8.1

func Typed[T any](s *FlagSet, name string, desc string, value T) func(context.Context) T

Typed registers a new flag that represents a value of type T.

If a Flag with the same name is already registered, the call will panic with an error that is ErrDuplicateFlag.

func TypedFunc added in v0.8.1

func TypedFunc[T any](s *FlagSet, name string, desc string, value func(context.Context) T) func(context.Context) T

TypedFunc registers a new flag that represents a value of type T value produced by calling the given function.

If a Flag with the same name is already registered, the call will panic with an error that is ErrDuplicateFlag.

Types

type Flag

type Flag struct {
	// Kind contains the flags kind or type.
	Kind FlagKind

	// Name is the name of the feature flag.
	Name string

	// Description is an optional description specified using [WithDescription].
	Description string
}

Flag represents a flag registered with a FlagSet.

type FlagKind added in v0.7.0

type FlagKind uint8

FlagKind is an enum of potential flag kinds.

const (
	// FlagKindInvalid is the zero value of FlagKind and is not considered valid value.
	FlagKindInvalid FlagKind = iota

	// FlagKindAny is used for flags created via [FlagSet.Any] and [FlagSet.AnyFunc].
	FlagKindAny

	// FlagKindBool is used for flags created via [FlagSet.Bool] and [FlagSet.BoolFunc].
	FlagKindBool

	// FlagKindDuration is used for flags created via [FlagSet.Duration] and [FlagSet.DurationFunc].
	FlagKindDuration

	// FlagKindInt is used for flags created via [FlagSet.Int] and [FlagSet.IntFunc].
	FlagKindInt

	// FlagKindFloat64 is used for flags created via [FlagSet.Float64] and [FlagSet.Float64Func].
	FlagKindFloat64

	// FlagKindString is used for flags created via [FlagSet.String] and [FlagSet.StringFunc].
	FlagKindString

	// FlagKindUint is used for flags created via [FlagSet.Uint] and [FlagSet.UintFunc].
	FlagKindUint
)

type FlagSet added in v0.6.0

type FlagSet struct {
	// contains filtered or unexported fields
}

FlagSet represents a set of defined feature flags.

The zero value is valid and returns zero values for all flags.

A FlagSet must not be copied and should instead be passed around via pointer.

func (*FlagSet) All added in v0.6.0

func (s *FlagSet) All(yield func(Flag) bool)

All yields all registered flags sorted by name.

func (*FlagSet) Any added in v0.8.1

func (s *FlagSet) Any(name string, desc string, value any) func(context.Context) any

Any registers a new flag that represents an arbitrary value.

If a Flag with the same name is already registered, the call will panic with an error that is ErrDuplicateFlag.

func (*FlagSet) AnyFunc added in v0.8.1

func (s *FlagSet) AnyFunc(name string, desc string, valueFn func(context.Context) any) func(context.Context) any

AnyFunc registers a new flag that represents an arbitrary value produced by calling the given function.

If a Flag with the same name is already registered, the call will panic with an error that is ErrDuplicateFlag.

func (*FlagSet) Bool added in v0.6.0

func (s *FlagSet) Bool(name string, desc string, value bool) func(context.Context) bool

Bool registers a new flag that represents a boolean value.

If a Flag with the same name is already registered, the call will panic with an error that is ErrDuplicateFlag.

func (*FlagSet) BoolFunc added in v0.8.1

func (s *FlagSet) BoolFunc(name string, desc string, valueFn func(context.Context) bool) func(context.Context) bool

BoolFunc registers a new flag that represents a boolean value produced by calling the given function.

If a Flag with the same name is already registered, the call will panic with an error that is ErrDuplicateFlag.

func (*FlagSet) Context added in v0.7.0

func (s *FlagSet) Context(ctx context.Context, values ...Value) context.Context

Context returns a new context based on ctx which will use the given values when checking feature flags of this set.

If a values type does not match the flags type, Context will panic.

Values with no matching flag are ignored.

func (*FlagSet) Duration added in v0.8.1

func (s *FlagSet) Duration(name string, desc string, value time.Duration) func(context.Context) time.Duration

Duration registers a new flag that represents a duration value.

If a Flag with the same name is already registered, the call will panic with an error that is ErrDuplicateFlag.

func (*FlagSet) DurationFunc added in v0.8.1

func (s *FlagSet) DurationFunc(name string, desc string, valueFn func(context.Context) time.Duration) func(context.Context) time.Duration

DurationFunc registers a new flag that represents a duration value produced by calling the given function.

If a Flag with the same name is already registered, the call will panic with an error that is ErrDuplicateFlag.

func (*FlagSet) Float64 added in v0.8.1

func (s *FlagSet) Float64(name string, desc string, value float64) func(context.Context) float64

Float64 registers a new flag that represents a floating point value.

If a Flag with the same name is already registered, the call will panic with an error that is ErrDuplicateFlag.

func (*FlagSet) Float64Func added in v0.8.1

func (s *FlagSet) Float64Func(name string, desc string, valueFn func(context.Context) float64) func(context.Context) float64

Float64Func registers a new flag that represents a floating point value produced by calling the given function.

If a Flag with the same name is already registered, the call will panic with an error that is ErrDuplicateFlag.

func (*FlagSet) Int added in v0.6.0

func (s *FlagSet) Int(name string, desc string, value int) func(context.Context) int

Int registers a new flag that represents an integer value.

If a Flag with the same name is already registered, the call will panic with an error that is ErrDuplicateFlag.

func (*FlagSet) IntFunc added in v0.8.1

func (s *FlagSet) IntFunc(name string, desc string, valueFn func(context.Context) int) func(context.Context) int

IntFunc registers a new flag that represents an integer value produced by calling the given function.

If a Flag with the same name is already registered, the call will panic with an error that is ErrDuplicateFlag.

func (*FlagSet) Lookup added in v0.6.0

func (s *FlagSet) Lookup(name string) (Flag, bool)

Lookup returns the flag with the given name.

func (*FlagSet) String added in v0.6.0

func (s *FlagSet) String(name string, desc string, value string) func(context.Context) string

String registers a new flag that represents a string value.

If a Flag with the same name is already registered, the call will panic with an error that is ErrDuplicateFlag.

func (*FlagSet) StringFunc added in v0.8.1

func (s *FlagSet) StringFunc(name string, desc string, valueFn func(context.Context) string) func(context.Context) string

StringFunc registers a new flag that represents a string value produced by calling the given function.

If a Flag with the same name is already registered, the call will panic with an error that is ErrDuplicateFlag.

func (*FlagSet) Uint added in v0.7.0

func (s *FlagSet) Uint(name string, desc string, value uint) func(context.Context) uint

Uint registers a new flag that represents an unsigned integer value.

If a Flag with the same name is already registered, the call will panic with an error that is ErrDuplicateFlag.

func (*FlagSet) UintFunc added in v0.8.1

func (s *FlagSet) UintFunc(name string, desc string, valueFn func(context.Context) uint) func(context.Context) uint

UintFunc registers a new flag that represents an unsigned integer value produced by calling the given function.

If a Flag with the same name is already registered, the call will panic with an error that is ErrDuplicateFlag.

type Value added in v0.7.0

type Value struct {
	// contains filtered or unexported fields
}

Value specifies a custom value for a feature flag, which can be assigned to a context.Context.

A Value must be created using one of BoolValue, DurationValue, Float64Value, IntValue, StringValue or UintValue.

func AnyValue added in v0.8.1

func AnyValue(name string, value any) Value

AnyValue returns a Value that can be passed to FlagSet.Context to override the value for the given flag.

func BoolValue added in v0.7.0

func BoolValue(name string, value bool) Value

BoolValue returns a Value that can be passed to FlagSet.Context to override the value for the given flag.

func DurationValue added in v0.8.1

func DurationValue(name string, value time.Duration) Value

DurationValue returns a Value that can be passed to FlagSet.Context to override the value for the given flag.

func Float64Value added in v0.8.1

func Float64Value(name string, value float64) Value

Float64Value returns a Value that can be passed to FlagSet.Context to override the value for the given flag.

func IntValue added in v0.7.0

func IntValue(name string, value int) Value

IntValue returns a Value that can be passed to FlagSet.Context to override the value for the given flag.

func StringValue added in v0.7.0

func StringValue(name string, value string) Value

StringValue returns a Value that can be passed to FlagSet.Context to override the value for the given flag.

func UintValue added in v0.7.0

func UintValue(name string, value uint) Value

UintValue returns a Value that can be passed to FlagSet.Context to override the value for the given flag.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL