Documentation
¶
Overview ¶
Example ¶
package main
import (
"fmt"
"sort"
"time"
"github.com/worldline-go/struct2"
)
func sortPrint(m map[string]any) {
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
fmt.Printf("Type: %T, Value: %v\n", m[k], m[k])
}
}
func main() {
type ColorGroup struct {
ID int `json:"id"`
Name string `json:"name"`
Colors []string `json:"colors"`
Date timeCustom `json:"time"`
}
d, _ := time.Parse(time.RFC3339, "2006-01-02T15:04:05Z")
group := ColorGroup{
ID: 1,
Name: "Reds",
Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
Date: timeCustom{Time: d},
}
result := new(struct2.Decoder).SetTagName("json").Map(group) // default tag name is "struct"
// fmt.Printf("%#v", result)
sortPrint(result)
}
Output: Type: []string, Value: [Crimson Red Ruby Maroon] Type: int, Value: 1 Type: string, Value: Reds Type: time.Time, Value: 2006-01-02 15:04:05 +0000 UTC
Example (CustomHook) ¶
package main
import (
"fmt"
"reflect"
"github.com/worldline-go/struct2"
)
func main() {
type ColorGroup struct {
Name string `db:"name"`
Count int `db:"count"`
}
group := ColorGroup{
Name: "DeepCore",
}
decoder := struct2.Decoder{
TagName: "db",
Hooks: []struct2.HookFunc{func(v reflect.Value) (any, error) {
if v.Kind() == reflect.String {
return "str_" + v.Interface().(string), nil
}
return nil, struct2.ErrContinueHook
}},
}
result := decoder.Map(group)
fmt.Printf("%v", result["name"])
}
Output: str_DeepCore
Example (MapToStruct) ¶
package main
import (
"fmt"
"reflect"
"time"
"github.com/worldline-go/struct2"
)
func main() {
type SubCfg struct {
Enabled bool `cfg:"enabled"`
}
type Config struct {
Name string `cfg:"name"`
Count int `cfg:"count"`
Sub SubCfg `cfg:"sub"`
Time time.Duration `cfg:"time"`
}
decoder := struct2.Decoder{
TagName: "cfg",
HooksDecode: []struct2.HookDecodeFunc{func(in reflect.Type, out reflect.Type, data any) (any, error) {
if out == reflect.TypeFor[time.Duration]() {
switch in.Kind() {
case reflect.String:
return time.ParseDuration(data.(string))
}
}
return data, nil
}},
WeaklyTypedInput: true,
WeaklyIgnoreSeperator: true,
WeaklyDashUnderscore: true,
}
cfgMap := map[string]any{
"name": "Altay",
"count": "42",
"sub": map[string]any{
"enabled": "true",
},
"time": "1h30m",
}
var cfg Config
if err := decoder.Decode(cfgMap, &cfg); err != nil {
fmt.Printf("decode error: %v", err)
return
}
fmt.Printf("%v %v %v %v", cfg.Name, cfg.Count, cfg.Sub.Enabled, cfg.Time)
}
Output: Altay 42 true 1h30m0s
Index ¶
- Variables
- func Ptr2Concrete(val any) any
- func WithOmitNested() optionMap
- type Decoder
- func (d *Decoder) Decode(input, output any) error
- func (d *Decoder) GetFields(s any) []string
- func (d *Decoder) Map(input any, opts ...optionMap) map[string]any
- func (d *Decoder) MapOmitNested(input any) map[string]anydeprecated
- func (d *Decoder) MapSlice(input any, opts ...optionMap) []map[string]any
- func (d *Decoder) SetHooks(hooks []HookFunc) *Decoder
- func (d *Decoder) SetHooksDecode(hooksDecode []HookDecodeFunc) *Decoder
- func (d *Decoder) SetTagName(t string) *Decoder
- type HookDecodeFunc
- type HookFunc
- type Hooker
Examples ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var ErrContinueHook = errors.New("continue to decode")
ErrContinueHook usable with HookFunc. This error type not checking by decode. Replacable by any error to continue to decode.
Functions ¶
func Ptr2Concrete ¶
func WithOmitNested ¶ added in v1.4.0
func WithOmitNested() optionMap
Types ¶
type Decoder ¶
type Decoder struct {
// Tagname to lookup struct's field tag, default is `struct`
TagName string
// Hooks function run before decode and enable to change of data.
Hooks []HookFunc
// HooksDecode to modify data before decode.
HooksDecode []HookDecodeFunc
// WeaklyTypedInput is true, the decoder will make the following
// "weak" conversions:
//
// - bools to string (true = "1", false = "0")
// - numbers to string (base 10)
// - bools to int/uint (true = 1, false = 0)
// - strings to int/uint (base implied by prefix)
// - int to bool (true if value != 0)
// - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F,
// FALSE, false, False. Anything else is an error)
// - empty array = empty map and vice versa
// - negative numbers to overflowed uint values (base 10)
// - slice of maps to a merged map
// - single values are converted to slices if required. Each
// element is weakly decoded. For example: "4" can become []int{4}
// if the target type is an int slice.
//
WeaklyTypedInput bool
// ZeroFields, if set to true, will zero fields before writing them.
// For example, a map will be emptied before decoded values are put in
// it. If this is false, a map will be merged.
ZeroFields bool
// Squash will squash embedded structs. A squash tag may also be
// added to an individual struct field using a tag. For example:
//
// type Parent struct {
// Child `struct:",squash"`
// }
Squash bool
// IgnoreUntaggedFields ignores all struct fields without explicit
// TagName, comparable to `struct:"-"` as default behaviour.
IgnoreUntaggedFields bool
// BackupTagName usable if TagName not found.
BackupTagName string
// WeaklyDashUnderscore apply underscore/dash conversion to variables
// on map to struct. variable_name == variable-name.
WeaklyDashUnderscore bool
// WeaklyIgnoreSeperator ignore seperator on map to struct. variable_name == variablename
// values are -, _ and space.
WeaklyIgnoreSeperator bool
// ForcePtr2 assume `struct:",ptr2` on all pointer struct fields.
ForcePtr2 bool
// OmitNullPtr omits nil pointers, in the map.
OmitNilPtr bool
// OutputCamelCase will convert map keys to camel case.
OuputCamelCase bool
// NoRemainFields will fail if there are extra fields in the input, that are not in the output.
NoRemainFields bool
}
Decoder is main struct of struct2, holds config and functions.
func (*Decoder) Map ¶
Map converts given struct to the map[string]any. Panic if input not a struct type.
func (*Decoder) MapOmitNested
deprecated
func (*Decoder) MapSlice ¶ added in v1.4.0
MapSlice converts given slice of structs to []map[string]any. Panic if input not a slice or array type.
func (*Decoder) SetHooksDecode ¶ added in v1.2.2
func (d *Decoder) SetHooksDecode(hooksDecode []HookDecodeFunc) *Decoder
func (*Decoder) SetTagName ¶ added in v1.1.0
type HookDecodeFunc ¶ added in v1.2.2
HookDecodeFunc get input, output and data and return modified data.
Click to show internal directories.
Click to hide internal directories.