gowalker

package module
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Dec 19, 2024 License: MIT Imports: 9 Imported by: 1

README

Golang struct walker

Build Status codecov Go Report Card GoDoc Sourcegraph Release

Walking throught golang struct to fullfil its fields from ENV variables.

Install

$ go get github.com/vkd/gowalker

Example of the config parsing

import (
	"log"
	"os"

	"github.com/vkd/gowalker"
	"github.com/vkd/gowalker/config"
)

type Config struct {
	LogLevel string        `flag:"loglevel" env:"LOGLEVEL" required:"true"`
	Timeout  time.Duration `default:"3s"`

	DB  struct {
		Port  int `default:"5432" flag:"db-port" env:"DB_PORT"`
	}
}

func ParseConfig() {
	var cfg Config
	err := config.Walk(&cfg, log.New(os.Stdout, "", 0),
		gowalker.Flags(gowalker.FieldKey("flag", gowalker.Fullname("-", strings.ToLower)), os.Args),
		gowalker.Envs(gowalker.FieldKey("env", gowalker.Fullname("_", strings.ToUpper)), os.LookupEnv),
		gowalker.Tag("default"),
		gowalker.Required("required"),
	)
	if err != nil {
		if errors.Is(err, gowalker.ErrPrintHelp) {
			return nil
		}
		...
	}
}

Documentation

Overview

Example
package main

import (
	"fmt"
	"strings"
	"time"

	"github.com/vkd/gowalker"
	"github.com/vkd/gowalker/config"
	"golang.org/x/text/cases"
	"golang.org/x/text/language"
)

type titleName string

func (c *titleName) SetString(s string) error {
	*c = titleName(cases.Title(language.Und).String(s) + "!")
	return nil
}

func main() {
	var cfg struct {
		Name    titleName
		Timeout time.Duration `default:"3s"`

		DB struct {
			Username string `required:""`
			Password string `required:""`
		}

		Metrics struct {
			Addr string `env:"METRICS_URL"`
		}
	}

	// osLookupEnv := os.LookupEnv
	osLookupEnv := func(key string) (string, bool) {
		v, ok := map[string]string{
			"MY_ORG_DB_USERNAME": "postgres",
			"MY_ORG_METRICS_URL": "localhost:5678",
		}[key]
		return v, ok
	}

	// osArgs := os.Args
	osArgs := []string{"gowalker", "--timeout=5s", "--db-password", "example", "--name=gowalker"}

	err := config.Walk(&cfg, nil,
		gowalker.Flags(gowalker.FieldKey("flag", gowalker.Fullname("-", strings.ToLower)), osArgs),
		gowalker.Envs(gowalker.Prefix("MY_ORG_", gowalker.FieldKey("env", gowalker.Fullname("_", strings.ToUpper))), osLookupEnv),
		gowalker.Tag("default"),
		gowalker.Required("required"),
	)
	fmt.Printf("%v, %v", cfg, err)
}
Output:

{Gowalker! 5s {postgres example} {localhost:5678}}, <nil>

Index

Examples

Constants

This section is empty.

Variables

View Source
var DashToLoverNamer = Fullname("-", strings.ToLower)

DashToLoverNamer - concat a lowercase parent's name with a lowercase child's one with dash.

View Source
var DefaultNamer = Fullname("", nil)
View Source
var EnvNamer = UpperNamer

EnvNamer - STRUCT_FIELD naming.

View Source
var ErrPrintHelp = fmt.Errorf("print help")
View Source
var ErrRequiredField = errors.New("field is required")
View Source
var ErrUnsupportedValue = errors.New("unsupported type for value: allowed only ptr")

ErrUnsupportedValue is raised if value is passed not as a pointer.

View Source
var FlagNamer = DashToLoverNamer

FlagNamer - struct-field naming.

View Source
var StructFieldNamer = Fullname(".", nil)

StructFieldNamer - concat a parent's name with a child's one with dot.

View Source
var UpperNamer = Fullname("_", strings.ToUpper)

UpperNamer - concat a uppercase parent's name with a uppercase child's one with underscore.

Functions

func IsGoWalkerField added in v0.1.2

func IsGoWalkerField(value reflect.Value) bool

func KeyUpdatedFields added in v0.0.11

func KeyUpdatedFields(fs Fields) string

func Walk

func Walk(value interface{}, fs Fields, w Walker, cs ...Option) error

Walk - walk struct by all public fields.

Should be passed as pointer: type myStruct struct var s myStruct gowalker.Walk(&s, ...)

Example (CollectAllPublicFields)
package main

import (
	"fmt"
	"reflect"
	"time"

	"github.com/vkd/gowalker"
)

type visitedFields []string

func (f *visitedFields) Step(value reflect.Value, field reflect.StructField, fs gowalker.Fields) (set bool, err error) {
	key := gowalker.DashToLoverNamer.Key(fs.Names())
	*f = append(*f, key)
	return false, nil
}

func main() {
	var config struct {
		Name string
		Port int
		DB   struct {
			URL  string
			Port int
		}

		StartedAt time.Time
	}

	var fs visitedFields
	err := gowalker.Walk(&config, gowalker.MakeFields(2), &fs)
	fmt.Printf("fields: %v, %v", fs, err)
}
Output:

fields: [name port db-url db-port startedat], <nil>
Example (FromMapOfStrings)
package main

import (
	"fmt"
	"reflect"

	"github.com/vkd/gowalker"
	"github.com/vkd/gowalker/setter"
)

func main() {
	var q struct {
		Name    string   `uri:"name"`
		Age     int      `uri:"age"`
		Friends []string `uri:"friends"`
		Coins   []int    `uri:"coins"`
		Keys    []int
	}

	uri := map[string][]string{
		"name":    {"mike"},
		"friends": {"igor", "alisa"},
	}

	fk := gowalker.FieldKey("uri", gowalker.DefaultNamer)
	w := gowalker.WalkerFunc(func(value reflect.Value, field reflect.StructField, fs gowalker.Fields) (stop bool, _ error) {
		key := fk.FieldKey(field, fs)
		v, ok := uri[key]
		if !ok {
			return false, nil
		}
		return true, setter.SetSliceStrings(value, field, v)
	})
	err := gowalker.Walk(&q, gowalker.MakeFields(1), w)
	fmt.Printf("%+v, %v", q, err)
}
Output:

{Name:mike Age:0 Friends:[igor alisa] Coins:[] Keys:[]}, <nil>

Types

type DefaultTag added in v0.1.2

type DefaultTag Tag

func (DefaultTag) Doc added in v0.1.2

func (t DefaultTag) Doc(field reflect.StructField, fs Fields) string

func (DefaultTag) Name added in v0.1.2

func (t DefaultTag) Name() string

func (DefaultTag) Step added in v0.1.2

func (t DefaultTag) Step(value reflect.Value, field reflect.StructField, fs Fields) (bool, error)

type Env added in v0.0.11

type Env struct {
	FieldKeyer
	LookupFunc
}

func Envs added in v0.0.9

func Envs(fk FieldKeyer, osLookupEnv LookupFunc) *Env

func (*Env) Doc added in v0.0.11

func (e *Env) Doc(field reflect.StructField, fs Fields) string

func (*Env) Name added in v0.0.11

func (e *Env) Name() string

func (*Env) Step added in v0.0.11

func (e *Env) Step(value reflect.Value, field reflect.StructField, fs Fields) (bool, error)

type FieldKeyer added in v0.0.5

type FieldKeyer interface {
	FieldKey(reflect.StructField, Fields) string
}

func FieldKey added in v0.0.6

func FieldKey(t Tag, namer Namer) FieldKeyer

func NestedFieldKey added in v0.1.1

func NestedFieldKey(t, fkey Tag, namer Namer) FieldKeyer

func Prefix added in v0.0.14

func Prefix(p string, fk FieldKeyer) FieldKeyer

type FieldKeyerFunc added in v0.1.1

type FieldKeyerFunc func(reflect.StructField, Fields) string

func (FieldKeyerFunc) FieldKey added in v0.1.1

func (f FieldKeyerFunc) FieldKey(field reflect.StructField, fs Fields) string

type Fields added in v0.0.6

type Fields []reflect.StructField

func MakeFields added in v0.0.6

func MakeFields(cap int) Fields

func (Fields) Names added in v0.1.0

func (f Fields) Names() iter.Seq[string]

type Flag added in v0.0.5

type Flag struct {
	FieldKeyer
	OsArgs []string
	// contains filtered or unexported fields
}

func Flags added in v0.0.9

func Flags(fk FieldKeyer, osArgs []string) *Flag

func (*Flag) Doc added in v0.0.11

func (f *Flag) Doc(field reflect.StructField, fs Fields) string

func (*Flag) Init added in v0.0.11

func (f *Flag) Init(ptr interface{}) error

func (*Flag) Name added in v0.0.11

func (*Flag) Name() string

func (*Flag) Step added in v0.0.11

func (f *Flag) Step(v reflect.Value, sf reflect.StructField, fs Fields) (ok bool, _ error)

type GoWalkerFielder added in v0.1.2

type GoWalkerFielder interface {
	GoWalkerField()
}

type LookupFunc added in v0.0.11

type LookupFunc func(key string) (string, bool)

type Maybe added in v0.1.2

type Maybe[T any] struct {
	IsSet bool
	Value T
}

func (Maybe[T]) Get added in v0.1.2

func (m Maybe[T]) Get() (zero T, _ bool)

func (Maybe[T]) GoWalkerField added in v0.1.2

func (Maybe[T]) GoWalkerField()

func (Maybe[T]) GoWalkerMaybe added in v0.1.2

func (Maybe[T]) GoWalkerMaybe()

func (*Maybe[T]) Set added in v0.1.2

func (m *Maybe[T]) Set(v T)

type Namer added in v0.0.2

type Namer interface {
	Key(fs iter.Seq[string]) string
}

func Fullname added in v0.0.4

func Fullname(separator string, convFn func(string) string) Namer

Fullname namer.

type NamerFunc added in v0.1.1

type NamerFunc func(fs iter.Seq[string]) string

func (NamerFunc) Key added in v0.1.1

func (n NamerFunc) Key(fs iter.Seq[string]) string

type Option added in v0.0.17

type Option interface {
	// contains filtered or unexported methods
}

func StepOnStructFields added in v0.0.17

func StepOnStructFields() Option

type Required added in v0.0.6

type Required Tag

func (Required) Doc added in v0.0.11

func (r Required) Doc(field reflect.StructField, fs Fields) string

func (Required) Name added in v0.0.11

func (r Required) Name() string

func (Required) Step added in v0.0.11

func (r Required) Step(value reflect.Value, field reflect.StructField, fs Fields) (bool, error)

type Tag added in v0.0.4

type Tag string

func (Tag) Doc added in v0.0.11

func (t Tag) Doc(field reflect.StructField, fs Fields) string

func (Tag) Name added in v0.0.11

func (t Tag) Name() string

func (Tag) Names added in v0.1.0

func (t Tag) Names(f Fields) iter.Seq[string]

func (Tag) Step added in v0.0.4

func (t Tag) Step(value reflect.Value, field reflect.StructField, fs Fields) (bool, error)

type UpdatedFields added in v0.0.6

type UpdatedFields map[string]struct{}

func FlagWalk added in v0.0.6

func FlagWalk(ptr interface{}, fs Fields, kb FieldKeyer, osArgs []string) (UpdatedFields, error)

func (UpdatedFields) Has added in v0.0.11

func (u UpdatedFields) Has(fs Fields) bool

type Walker

type Walker interface {
	Step(reflect.Value, reflect.StructField, Fields) (stop bool, _ error)
}

type WalkerFunc

type WalkerFunc func(reflect.Value, reflect.StructField, Fields) (stop bool, _ error)

func (WalkerFunc) Step

func (f WalkerFunc) Step(value reflect.Value, field reflect.StructField, fs Fields) (bool, error)

type WalkersOR added in v0.0.11

type WalkersOR []Walker

func (WalkersOR) Step added in v0.0.11

func (w WalkersOR) Step(value reflect.Value, field reflect.StructField, fs Fields) (bool, error)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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