Import path:
gitlab.soludian.com/soludian/fountain/libs/base/structs
structs
import "gitlab.soludian.com/soludian/fountain/libs/base/structs"Package structs Provide some extends util functions for struct. eg: tag parse, struct init, value set
Index
- Variables
- func ExportPrivate(opt *MapOptions)
- func FillJSONFields[T any](t T) T
- func Init(ptr any, optFns ...InitOptFunc) error
- func InitDefaults(ptr any, optFns ...InitOptFunc) error
- func IsExported(name string) bool
- func IsUnexported(name string) bool
- func MarshalData(t any) error
- func MergeAnonymous(opt *MapOptions)
- func MustToMap(st any, optFns ...MapOptFunc) map[string]any
- func MustToSMap(st any, optFns ...MapOptFunc) map[string]string
- func ParseReflectTags(rt reflect.Type, tagNames []string) (map[string]map_util.SMap, error)
- func ParseTagValueDefault(field, tagVal string) (mp map_util.SMap, err error)
- func ParseTagValueNamed(field, tagVal string, keys ...string) (mp map_util.SMap, err error)
- func ParseTagValueQuick(tagVal string, defines []string) map_util.SMap
- func ParseTags(st any, tagNames []string) (map[string]map_util.SMap, error)
- func SetValues(ptr any, data map[string]any, optFns ...SetOptFunc) error
- func StructName(v any) string
- func StructToMap(st any, optFns ...MapOptFunc) (map[string]any, error)
- func ToMap(st any, optFns ...MapOptFunc) map[string]any
- func ToSMap(st any, optFns ...MapOptFunc) map[string]string
- func ToString(st any, optFns ...MapOptFunc) string
- func TryToMap(st any, optFns ...MapOptFunc) (map[string]any, error)
- func TryToSMap(st any, optFns ...MapOptFunc) (map[string]string, error)
- func WithParseDefault(opt *SetOptions)
- type Aliases
- func NewAliases(checker func(alias string)) *Aliases
- func (as *Aliases) AddAlias(real, alias string)
- func (as *Aliases) AddAliasMap(alias2real map[string]string)
- func (as *Aliases) AddAliases(real string, aliases []string)
- func (as *Aliases) HasAlias(alias string) bool
- func (as *Aliases) Mapping() map[string]string
- func (as *Aliases) ResolveAlias(alias string) string
- type Data
- func NewData() *Data
- func NewLiteData(data map[string]any) *Data
- func (d *Data) BoolVal(key string) bool
- func (d *Data) Data() map[string]any
- func (d *Data) DataLen() int
- func (d *Data) EnableLock() *Data
- func (d *Data) Get(key string) any
- func (d *Data) GetVal(key string) any
- func (d *Data) IntVal(key string) int
- func (d *Data) Merge(mp map[string]any)
- func (d *Data) ResetData()
- func (d *Data) Set(key string, val any)
- func (d *Data) SetData(data map[string]any)
- func (d *Data) SetValue(key string, val any)
- func (d *Data) StrVal(key string) string
- func (d *Data) String() string
- func (d *Data) Value(key string) (val any, ok bool)
- func (d *Data) WithLock() *Data
- type InitOptFunc
- type InitOptions
- type LiteData
- type MapOptFunc
- type MapOptions
- type OrderedData
- type SMap
- type SetOptFunc
- type SetOptions
- type TagParser
- type TagValFunc
- type Value
- func GetFieldValueByTag(st any, tag, tagValue string) (*Value, error)
- func NewValue(val any) *Value
- func (v *Value) Bool() bool
- func (v *Value) Float64() float64
- func (v *Value) Int() int
- func (v *Value) Int64() int64
- func (v *Value) IsEmpty() bool
- func (v *Value) Reset()
- func (v *Value) Set(val any)
- func (v *Value) SplitToInts(sep ...string) (ss []int)
- func (v *Value) SplitToStrings(sep ...string) (ss []string)
- func (v *Value) String() string
- func (v *Value) Strings() (ss []string)
- func (v *Value) Val() any
- type Wrapper
Variables
ErrNotAnStruct error var emptyStringMap = make(map_util.SMap)
var ErrNotAnStruct = errors.New("must input an struct value")func ExportPrivate
func ExportPrivate(opt *MapOptions)ExportPrivate merge anonymous struct fields to parent map
func FillJSONFields
func FillJSONFields[T any](t T) TBefore save data from Database, need call FillJSONFields to fill all slice fields Description: The FillJSONFields function is designed to automatically populate fields within a struct by converting JSON representations to their corresponding types. This function leverages Go's reflection capabilities to identify and perform the conversion for fields based on field name/tag conventions. To use the FillJSONFields function, you should provide a struct variable or a pointer to a struct. The function will identify fields in the struct that require population based on the field name conventions and perform the population process.
FillJSONFields tự động chuyển các trường chứa chuỗi json thành các trường tương ứng dựa vào tag "marshal_<to/from>:"<FieldName/tag:tagValue/tag=tagValue>" hoặc suffix "JSON" (field json nguồn).
Parameters: t: A variable or a pointer to a struct that contains the fields to be populated with JSON data.
Return: Returns a value of the same type as the input t. If t is a pointer, the function returns a pointer to the populated struct; otherwise, it returns the populated struct directly.
Field Name Conventions: This function relies on field name conventions to determine fields requiring population: Fields to be populated from JSON data must have the "JSON" suffix. Fields that hold the corresponding data in JSON format should have the same name as the JSON field but without the "JSON" suffix.
Usage:
type Person struct {
Name string
NameJSON string
Age int
AgeJ string `marshal_from:"Age"`
Value int `marshal_to:"json=value_j"`
ValueJ string `json:"value_j"`
}
func main() {
person := &Person{
NameJSON: `"Name"`,
AgeJ: `"12"`,
ValueJ: `"21"`,
}
populatedPerson := FillJSONFields(person)
fmt.Println("Name:", populatedPerson.Name)
fmt.Println("Age:", populatedPerson.Age)
}func Init
func Init(ptr any, optFns ...InitOptFunc) errorInit struct default value by field "default" tag.
func InitDefaults
func InitDefaults(ptr any, optFns ...InitOptFunc) errorInitDefaults init struct default value by field "default" tag.
TIPS:
Support init field types: string, bool, intX, uintX, floatX, array, sliceExample:
type User1 struct {
Name string `default:"inhere"`
Age int32 `default:"30"`
}
u1 := &User1{}
err = structs.InitDefaults(u1)
fmt.Printf("%+v\n", u1) // Output: {Name:inhere Age:30}Example
package main
import (
"fmt"
"gitlab.soludian.com/soludian/fountain/libs/base/dump"
"gitlab.soludian.com/soludian/fountain/libs/base/structs"
)
func main() {
type Extra struct {
City string `default:"chengdu"`
Github string `default:"https://github.com/inhere"`
}
type User struct {
Name string `default:"inhere"`
Age int `default:"30"`
Extra Extra `default:""` // add tag for init sub struct
}
u := &User{}
_ = structs.InitDefaults(u)
dump.P(u)
/*dump:
&structs_test.User {
Name: string("inhere"), #len=6
Age: int(30),
Extra: structs_test.Extra {
City: string("chengdu"), #len=7
Github: string("https://github.com/inhere"), #len=25
},
},
*/
fmt.Println("Name:", u.Name)
fmt.Println("Age:", u.Age)
fmt.Println("Extra.City:", u.Extra.City)
fmt.Println("Extra.Github:", u.Extra.Github)
}Output
Name: inhere
Age: 30
Extra.City: chengdu
Extra.Github: https://github.com/inherefunc IsExported
func IsExported(name string) boolIsExported field name on struct
func IsUnexported
func IsUnexported(name string) boolIsUnexported field name on struct
func MarshalData
func MarshalData(t any) errorAfter get data from Database, need call MarshalData to fill all slice fields; MarshalData tự động chuyển đổi các trường không phải kiểu nguyên tố thành JSON tương ứng với field nguồn/đích có tag tag "marshal_<to/from>:"<FieldName/tag:tagValue/tag=tagValue>", suffix "JSON".
Description: The MarshalData function is used to automatically convert fields within a struct between JSON format and string format. This function utilizes the flexibility of reflection in Go to identify fields to be converted based on field name conventions and performs the conversion process.
To use the MarshalData function, you need to pass a pointer to a struct variable. The function will automatically identify fields in the struct that need conversion based on field name conventions and perform the conversion process.
Parameters: t: A variable of type pointer to a struct containing the data to be converted.
Return error: Returns nil if the conversion process is successful. Returns an error if an issue occurs during the conversion process.
Field Name Conventions: This function relies on field name conventions to determine fields requiring conversion: Fields to be converted from JSON to string format must have the "JSON" suffix. Fields to be converted from string to JSON format must have the same name as the corresponding JSON field, but without the "JSON" suffix.
Benchmark 1: BenchmarkUnmarshalJSON/MarshalData-12 135957 8628 ns/op 3124 B/op 124 allocs/op
Usage:
type Person struct {
Scopes []string `json:"scopes,omitempty" marshal_to:"ScopesJ"`
ScopesJ string `json:"name_j" unmarshal_from:"json:scopes"`
Age int `json:"age" marshal_to:"AgeJ"`
AgeJ string `json:"age_j" marshal_to:"Age"`
}
func main() {
person := &Person{
ScopesJ: `{"first_name": "John", "last_name": "Doe"}`,
AgeJSON: `"30"`,
}
err := UnmarshalJSON(person)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Name:", person.Scopes)
fmt.Println("Age:", person.Age)
}func MergeAnonymous
func MergeAnonymous(opt *MapOptions)MergeAnonymous merge anonymous struct fields to parent map
func MustToMap
func MustToMap(st any, optFns ...MapOptFunc) map[string]anyMustToMap alis of TryToMap, but will panic on error
func MustToSMap
func MustToSMap(st any, optFns ...MapOptFunc) map[string]stringMustToSMap alias of ToStringMap(), but will panic on error
func ParseReflectTags
func ParseReflectTags(rt reflect.Type, tagNames []string) (map[string]map_util.SMap, error)ParseReflectTags parse struct tags info.
func ParseTagValueDefault
func ParseTagValueDefault(field, tagVal string) (mp map_util.SMap, err error)ParseTagValueDefault parse like json tag value.
see json.Marshal():
// JSON as key "myName", skipped if empty.
Field int `json:"myName,omitempty"`
// Field appears in JSON as key "Field" (the default), but skipped if empty.
Field int `json:",omitempty"`
// Field is ignored by this package.
Field int `json:"-"`
// Field appears in JSON as key "-".
Field int `json:"-,"`
Int64String int64 `json:",string"`Returns:
{
"name": "myName", // maybe is empty, on tag value is "-"
"omitempty": "true",
"string": "true",
// ... more custom bool settings.
}func ParseTagValueNamed
func ParseTagValueNamed(field, tagVal string, keys ...string) (mp map_util.SMap, err error)ParseTagValueNamed parse k-v tag value string. it's like INI format contents.
Examples:
eg: "name=val0;shorts=i;required=true;desc=a message"
=>
{name: val0, shorts: i, required: true, desc: a message}func ParseTagValueQuick
func ParseTagValueQuick(tagVal string, defines []string) map_util.SMapParseTagValueQuick quick parse tag value string by sep(;)
func ParseTags
func ParseTags(st any, tagNames []string) (map[string]map_util.SMap, error)ParseTags for parse struct tags.
func SetValues
func SetValues(ptr any, data map[string]any, optFns ...SetOptFunc) errorSetValues set values to struct ptr from map data.
TIPS:
Only support set: string, bool, intX, uintX, floatXfunc StructName
func StructName(v any) stringStructName returns a normalized name of the passed structure.
func StructToMap
func StructToMap(st any, optFns ...MapOptFunc) (map[string]any, error)StructToMap quickly convert structs to map[string]any by reflect. Can custom export field name by tag `json` or custom tag
func ToMap
func ToMap(st any, optFns ...MapOptFunc) map[string]anyToMap quickly convert structs to map by reflect
Example
package main
import (
"fmt"
"gitlab.soludian.com/soludian/fountain/libs/base/dump"
"gitlab.soludian.com/soludian/fountain/libs/base/structs"
)
func main() {
type Extra struct {
City string `json:"city"`
Github string `json:"github"`
}
type User struct {
Name string `json:"name"`
Age int `json:"age"`
Extra Extra `json:"extra"`
}
u := &User{
Name: "inhere",
Age: 30,
Extra: Extra{
City: "chengdu",
Github: "https://github.com/inhere",
},
}
mp := structs.ToMap(u)
dump.P(mp)
/*dump:
map[string]interface {} { #len=3
"name": string("inhere"), #len=6
"age": int(30),
"extra": map[string]interface {} { #len=2
"city": string("chengdu"), #len=7
"github": string("https://github.com/inhere"), #len=25
},
},
*/
fmt.Println("mp.ame:", mp["name"])
fmt.Println("mp.age:", mp["age"])
}Output
mp.ame: inhere
mp.age: 30func ToSMap
func ToSMap(st any, optFns ...MapOptFunc) map[string]stringToSMap quickly and safe convert structs to map[string]string by reflect
func ToString
func ToString(st any, optFns ...MapOptFunc) stringToString quickly format struct to string
func TryToMap
func TryToMap(st any, optFns ...MapOptFunc) (map[string]any, error)TryToMap simple convert structs to map by reflect
func TryToSMap
func TryToSMap(st any, optFns ...MapOptFunc) (map[string]string, error)TryToSMap quickly convert structs to map[string]string by reflect
func WithParseDefault
func WithParseDefault(opt *SetOptions)WithParseDefault value by tag "default"
type Aliases
Aliases implemented a simple string alias map.
type Aliases struct {
// Checker custom add alias name checker func
Checker func(alias string) // should return bool OR error ??
// contains filtered or unexported fields
}func NewAliases
func NewAliases(checker func(alias string)) *AliasesNewAliases create
func (*Aliases) AddAlias
func (as *Aliases) AddAlias(real, alias string)AddAlias to the Aliases
func (*Aliases) AddAliasMap
func (as *Aliases) AddAliasMap(alias2real map[string]string)AddAliasMap to the Aliases
func (*Aliases) AddAliases
func (as *Aliases) AddAliases(real string, aliases []string)AddAliases to the Aliases
func (*Aliases) HasAlias
func (as *Aliases) HasAlias(alias string) boolHasAlias in the Aliases
func (*Aliases) Mapping
func (as *Aliases) Mapping() map[string]stringMapping get all aliases mapping
func (*Aliases) ResolveAlias
func (as *Aliases) ResolveAlias(alias string) stringResolveAlias by given name.
type Data
Data struct, allow enable lock
type Data struct {
sync.RWMutex
// contains filtered or unexported fields
}func NewData
func NewData() *DataNewData create new data instance
func NewLiteData
func NewLiteData(data map[string]any) *DataNewLiteData create, not locked
func (*Data) BoolVal
func (d *Data) BoolVal(key string) boolBoolVal get from data
func (*Data) Data
func (d *Data) Data() map[string]anyData get all
func (*Data) DataLen
func (d *Data) DataLen() intDataLen of data
func (*Data) EnableLock
func (d *Data) EnableLock() *DataEnableLock for operate data
func (*Data) Get
func (d *Data) Get(key string) anyGet val from data
func (*Data) GetVal
func (d *Data) GetVal(key string) anyGetVal get from data
func (*Data) IntVal
func (d *Data) IntVal(key string) intIntVal get from data
func (*Data) Merge
func (d *Data) Merge(mp map[string]any)Merge load new data
func (*Data) ResetData
func (d *Data) ResetData()ResetData all data
func (*Data) Set
func (d *Data) Set(key string, val any)Set value to data
func (*Data) SetData
func (d *Data) SetData(data map[string]any)SetData set all data
func (*Data) SetValue
func (d *Data) SetValue(key string, val any)SetValue to data
func (*Data) StrVal
func (d *Data) StrVal(key string) stringStrVal get from data
func (*Data) String
func (d *Data) String() stringString format data
func (*Data) Value
func (d *Data) Value(key string) (val any, ok bool)Value get from data
func (*Data) WithLock
func (d *Data) WithLock() *DataWithLock for operate data
type InitOptFunc
InitOptFunc define
type InitOptFunc func(opt *InitOptions)type InitOptions
InitOptions struct
type InitOptions struct {
// TagName default value tag name. tag: default
TagName string
// ParseEnv var name on default value. eg: `default:"${APP_ENV}"`
//
// default: false
ParseEnv bool
// ValueHook before set value hook TODO
ValueHook func(val string) any
}type LiteData
LiteData simple map[string]any struct. no lock
type LiteData = Datatype MapOptFunc
MapOptFunc define
type MapOptFunc func(opt *MapOptions)func WithMapTagName
func WithMapTagName(tagName string) MapOptFuncWithMapTagName set tag name for map field
type MapOptions
MapOptions for convert struct to map
type MapOptions struct {
// TagName for map filed. default is "json"
TagName string
// ParseDepth for parse. TODO support depth
ParseDepth int
// MergeAnonymous struct fields to parent map. default is true
MergeAnonymous bool
// ExportPrivate export private fields. default is false
ExportPrivate bool
}type OrderedData
OrderedData data TODO
type OrderedData struct {
map_util.Data
// contains filtered or unexported fields
}func NewOrderedData
func NewOrderedData(cap int) *OrderedDataNewOrderedData instance.
func (*OrderedData) Load
func (om *OrderedData) Load(data map[string]any)Load data
func (*OrderedData) Set
func (om *OrderedData) Set(key string, val any)Set key and value to map
type SMap
SMap simple map[string]string struct.
type SMap struct {
// contains filtered or unexported fields
}type SetOptFunc
SetOptFunc define
type SetOptFunc func(opt *SetOptions)type SetOptions
SetOptions for set values to struct
type SetOptions struct {
// FieldTagName get field name for read value. default tag: json
FieldTagName string
// ValueHook before set value hook TODO
ValueHook func(val any) any
// ParseDefault init default value by DefaultValTag tag value.
// default: false
//
// see InitDefaults()
ParseDefault bool
// DefaultValTag name. tag: default
DefaultValTag string
// ParseDefaultEnv parse env var on default tag. eg: `default:"${APP_ENV}"`
//
// default: false
ParseDefaultEnv bool
}type TagParser
TagParser struct
type TagParser struct {
// TagNames want parsed tag names.
TagNames []string
// ValueFunc tag value parse func.
ValueFunc TagValFunc
// contains filtered or unexported fields
}func NewTagParser
func NewTagParser(tagNames ...string) *TagParserNewTagParser instance
func (*TagParser) Info
func (p *TagParser) Info(field, tag string) (map_util.SMap, error)Info parse the give field, returns tag value info.
info, err := p.Info("Name", "json")
exportField := info.Get("name")func (*TagParser) Parse
func (p *TagParser) Parse(st any) errorParse an struct value
Example
package main
import (
"fmt"
"gitlab.soludian.com/soludian/fountain/libs/base/dump"
"gitlab.soludian.com/soludian/fountain/libs/base/fn"
"gitlab.soludian.com/soludian/fountain/libs/base/structs"
)
func main() {
type User struct {
Age int `json:"age" yaml:"age" default:"23"`
Name string `json:"name,omitempty" yaml:"name" default:"inhere"`
inner string //lint:ignore U1000 for test
}
u := &User{}
p := structs.NewTagParser("json", "yaml", "default")
fn.MustOK(p.Parse(u))
tags := p.Tags()
dump.P(tags)
/*tags:
map[string]map_util.SMap { #len=2
"Age": map_util.SMap { #len=3
"json": string("age"), #len=3
"yaml": string("age"), #len=3
"default": string("23"), #len=2
},
"Name": map_util.SMap { #len=3
"default": string("inhere"), #len=6
"json": string("name,omitempty"), #len=14
"yaml": string("name"), #len=4
},
},
*/
dump.P(p.Info("name", "json"))
/*info:
map_util.SMap { #len=2
"name": string("name"), #len=4
"omitempty": string("true"), #len=4
},
*/
fmt.Println(
tags["Age"].Get("json"),
tags["Age"].Get("default"),
)
}Output
age 23Example (Parse Tag Value Define)
package main
import (
"fmt"
"gitlab.soludian.com/soludian/fountain/libs/base/dump"
"gitlab.soludian.com/soludian/fountain/libs/base/fn"
"gitlab.soludian.com/soludian/fountain/libs/base/structs"
)
func main() {
// eg: "desc;required;default;shorts"
type MyCmd struct {
Name string `flag:"set your name;false;INHERE;n"`
}
c := &MyCmd{}
p := structs.NewTagParser("flag")
sepStr := ";"
defines := []string{"desc", "required", "default", "shorts"}
p.ValueFunc = structs.ParseTagValueDefine(sepStr, defines)
fn.MustOK(p.Parse(c))
// dump.P(p.Tags())
/*
map[string]map_util.SMap { #len=1
"Name": map_util.SMap { #len=1
"flag": string("set your name;false;INHERE;n"), #len=28
},
},
*/
fmt.Println("tags:", p.Tags())
info, _ := p.Info("Name", "flag")
dump.P(info)
/*
map_util.SMap { #len=4
"desc": string("set your name"), #len=13
"required": string("false"), #len=5
"default": string("INHERE"), #len=6
"shorts": string("n"), #len=1
},
*/
}Output
tags: map[Name:{flag:set your name;false;INHERE;n}]func (*TagParser) ParseType
func (p *TagParser) ParseType(rt reflect.Type) errorParseType parse a struct type value
func (*TagParser) Tags
func (p *TagParser) Tags() map[string]map_util.SMapTags map data for struct fields
type TagValFunc
TagValFunc handle func
type TagValFunc func(field, tagVal string) (map_util.SMap, error)func ParseTagValueDefine
func ParseTagValueDefine(sep string, defines []string) TagValFuncParseTagValueDefine parse tag value string by given defines.
Examples:
eg: "desc;required;default;shorts"
type MyStruct {
Age int `flag:"int option message;;a,b"`
}
sepStr := ";"
defines := []string{"desc", "required", "default", "shorts"}type Value
Value data store
type Value struct {
// V value
V any
}func GetFieldValueByTag
func GetFieldValueByTag(st any, tag, tagValue string) (*Value, error)GetFieldValueByTag get value of st by tag:"tagValue"
Usage:
type User struct {
Age int `json:"age"`
}
user := &User{Age: 23}
data, err := structs.GetFieldValueByTag(user, "json", "age")
if err != nil {
// error handler
}
fmt.Printf(data) // 23func NewValue
func NewValue(val any) *ValueNewValue instance.
func (*Value) Bool
func (v *Value) Bool() boolBool value
func (*Value) Float64
func (v *Value) Float64() float64Float64 value
func (*Value) Int
func (v *Value) Int() intInt value get
func (*Value) Int64
func (v *Value) Int64() int64Int64 value
func (*Value) IsEmpty
func (v *Value) IsEmpty() boolIsEmpty value
func (*Value) Reset
func (v *Value) Reset()Reset value
func (*Value) Set
func (v *Value) Set(val any)Set value
func (*Value) SplitToInts
func (v *Value) SplitToInts(sep ...string) (ss []int)SplitToInts split string value to []int. sep default is comma(,)
func (*Value) SplitToStrings
func (v *Value) SplitToStrings(sep ...string) (ss []string)SplitToStrings split string value to strings. sep default is comma(,)
func (*Value) String
func (v *Value) String() stringString value
func (*Value) Strings
func (v *Value) Strings() (ss []string)Strings value
func (*Value) Val
func (v *Value) Val() anyVal get
type Wrapper
Wrapper struct for read or set field value
type Wrapper struct {
// FieldTagName field name for read/write value. default tag: json
FieldTagName string
// contains filtered or unexported fields
}func NewWrapper
func NewWrapper(src any) *WrapperNewWrapper create a struct wrapper
func NewWriter
func NewWriter(ptr any) *WrapperNewWriter create a struct writer
func Wrap
func Wrap(src any) *WrapperWrap create a struct wrapper
func WrapValue
func WrapValue(rv reflect.Value) *WrapperWrapValue create a struct wrapper
func (*Wrapper) Get
func (r *Wrapper) Get(name string) anyGet field value by name, name allow use dot syntax.
func (*Wrapper) Lookup
func (r *Wrapper) Lookup(name string) (val any, ok bool)Lookup field value by name, name allow use dot syntax.
func (*Wrapper) Set
func (r *Wrapper) Set(name string, val any) errorSet field value by name, name allow use dot syntax.
Generated by gomarkdoc