structs

package
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Feb 6, 2023 License: Apache-2.0 Imports: 12 Imported by: 0

README

Structs

Provide some extends util functions for struct. eg: convert, tag parse, struct data init

  • structs.Aliases - implemented a simple string alias map.
  • Convert a struct to map[string]any data
  • Quickly init struct default values by field "default" tag.
  • Quickly set struct field values by map data
  • Parse a struct and collect tags, and parse tag value
  • And more util functions ...

Install

go get github.com/zhangyiming748/pretty/structs

Go docs

Usage

Convert to map

structs.ToMap() can be quickly convert a struct value to map[string]any

Examples:

	type User1 struct {
		Name string `json:"name"`
		Age  int    `json:"age"`
		city string
	}

	u1 := &User1{
		Name: "inhere",
		Age:  34,
		city: "somewhere",
	}

	mp := structs.ToMap(u1)
	pretty.P(mp)

Output:

map[string]interface {} { #len=2
  "age": int(34),
  "name": string("inhere"), #len=6
},
Init default values

structs.InitDefaults Quickly init struct default value by field "default" tag.

Examples:

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
}

u := &User{}
_ = structs.InitDefaults(u, &structs.InitOptions{})
pretty.P(u)

Output:

&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
  },
},
Set values from map
data := map[string]interface{}{
    "name": "inhere",
    "age":  234,
    "tags": []string{"php", "go"},
    "city": "chengdu",
}

type User struct {
    Name string   `json:"name"`
    Age  int      `json:"age"`
    Tags []string `json:"tags"`
    City string   `json:"city"`
}

u := &User{}
err := structs.SetValues(u, data)
pretty.P(u)

Output:

&structs_test.User {
  Name: string("inhere"), #len=6
  Age: int(234),
  Tags: []string [ #len=2
    string("php"), #len=3
    string("go"), #len=2
  ],
  City: string("chengdu"), #len=7
},
Tags collect and parse

Parse a struct for collect tags, and parse tag value

Examples:

// 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)

goutil.MustOK(p.Parse(c))
pretty.P(p.Tags())

Output:

map[string]maputil.SMap { #len=1
  "Name": maputil.SMap { #len=1
    "flag": string("set your name;false;INHERE;n"), #len=28
  },
},

Parse tag value

info, _ := p.Info("Name", "flag")
pretty.P(info)

Output:

maputil.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
},

Functions API

func InitDefaults(ptr any, optFns ...InitOptFunc) error
func MustToMap(st any, optFns ...MapOptFunc) map[string]interface{}
func ParseReflectTags(rt reflect.Type, tagNames []string) (map[string]maputil.SMap, error)
func ParseTagValueDefault(field, tagVal string) (mp maputil.SMap, err error)
func ParseTagValueNamed(field, tagVal string, keys ...string) (mp maputil.SMap, err error)
func ParseTags(st any, tagNames []string) (map[string]maputil.SMap, error)
func SetValues(ptr any, data map[string]any, optFns ...SetOptFunc) error
func StructToMap(st any, optFns ...MapOptFunc) (map[string]interface{}, error)
func ToMap(st any, optFns ...MapOptFunc) map[string]interface{}
func TryToMap(st any, optFns ...MapOptFunc) (map[string]interface{}, error)
type Aliases struct{ ... }
    func NewAliases(checker func(alias string)) *Aliases
type Data struct{ ... }
    func NewData() *Data
type InitOptFunc func(opt *InitOptions)
type InitOptions struct{ ... }
type LiteData struct{ ... }
type MapOptFunc func(opt *MapOptions)
type MapOptions struct{ ... }
type SMap struct{ ... }
type SetOptFunc func(opt *SetOptions)
type SetOptions struct{ ... }
type TagParser struct{ ... }
    func NewTagParser(tagNames ...string) *TagParser
type TagValFunc func(field, tagVal string) (maputil.SMap, error)
    func ParseTagValueDefine(sep string, defines []string) TagValFunc
type Value struct{ ... }
    func NewValue(val any) *Value

Testings

go test -v ./structs/...

Test limit by regexp:

go test -v -run ^TestSetByKeys ./structs/...

Documentation

Overview

Package structs Provide some extends util functions for struct. eg: tag parse, struct init, value set

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrNotAnStruct = errors.New("must input an struct value")

ErrNotAnStruct error var emptyStringMap = make(maputil.SMap)

Functions

func InitDefaults

func InitDefaults(ptr any, optFns ...InitOptFunc) error

InitDefaults init struct default value by field "default" tag.

TIPS:

Support init field types: string, bool, intX, uintX, floatX, array, slice

Example:

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"
	"github.com/zhangyiming748/pretty"

	"github.com/zhangyiming748/pretty/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
	}

	u := &User{}
	_ = structs.InitDefaults(u)
	pretty.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/inhere

func IsExported

func IsExported(fieldName string) bool

IsExported field name on struct

func IsUnexported

func IsUnexported(fieldName string) bool

IsUnexported field name on struct

func MustToMap

func MustToMap(st any, optFns ...MapOptFunc) map[string]any

MustToMap alis of TryToMap, but will panic on error

func ParseReflectTags

func ParseReflectTags(rt reflect.Type, tagNames []string) (map[string]maputil.SMap, error)

ParseReflectTags parse struct tags info.

func ParseTagValueDefault

func ParseTagValueDefault(field, tagVal string) (mp maputil.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 maputil.SMap, err error)

ParseTagValueNamed parse k-v tag value string. it's like INI format contents.

eg: "name=int0;shorts=i;required=true;desc=int option message"

func ParseTags

func ParseTags(st any, tagNames []string) (map[string]maputil.SMap, error)

ParseTags for parse struct tags.

func SetValues

func SetValues(ptr any, data map[string]any, optFns ...SetOptFunc) error

SetValues set data values to struct ptr

TIPS:

Only support set: string, bool, intX, uintX, floatX

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]any

ToMap quickly convert structs to map by reflect

Example
package main

import (
	"fmt"
	"github.com/zhangyiming748/pretty"

	"github.com/zhangyiming748/pretty/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)
	pretty.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: 30

func ToString

func ToString(st any, optFns ...MapOptFunc) string

ToString format

func TryToMap

func TryToMap(st any, optFns ...MapOptFunc) (map[string]any, error)

TryToMap simple convert structs to map by reflect

Types

type Aliases

type Aliases struct {

	// Checker custom add alias name checker func
	Checker func(alias string) // should return bool OR error ??
	// contains filtered or unexported fields
}

Aliases implemented a simple string alias map.

func NewAliases

func NewAliases(checker func(alias string)) *Aliases

NewAliases 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) bool

HasAlias in the Aliases

func (*Aliases) Mapping

func (as *Aliases) Mapping() map[string]string

Mapping get all aliases mapping

func (*Aliases) ResolveAlias

func (as *Aliases) ResolveAlias(alias string) string

ResolveAlias by given name.

type Data

type Data struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

Data struct, allow enable lock TODO

func NewData

func NewData() *Data

NewData create

func (*Data) BoolVal

func (d *Data) BoolVal(key string) bool

BoolVal get from data

func (*Data) Data

func (d *Data) Data() map[string]any

Data get all

func (*Data) DataLen

func (d *Data) DataLen() int

DataLen of data

func (*Data) EnableLock

func (d *Data) EnableLock() *Data

EnableLock for operate data

func (*Data) Get

func (d *Data) Get(key string) any

Get val from data

func (*Data) GetVal

func (d *Data) GetVal(key string) any

GetVal get from data

func (*Data) IntVal

func (d *Data) IntVal(key string) int

IntVal get from 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) string

StrVal get from data

func (*Data) String

func (d *Data) String() string

String format data

func (*Data) Value

func (d *Data) Value(key string) (val any, ok bool)

Value get from data

type InitOptFunc

type InitOptFunc func(opt *InitOptions)

InitOptFunc define

type InitOptions

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
}

InitOptions struct

type LiteData

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

LiteData simple map[string]any struct. no lock

func (*LiteData) Data

func (d *LiteData) Data() map[string]any

Data get all

func (*LiteData) GetVal

func (d *LiteData) GetVal(key string) any

GetVal get from data

func (*LiteData) IntVal

func (d *LiteData) IntVal(key string) int

IntVal get from data

func (*LiteData) ResetData

func (d *LiteData) ResetData()

ResetData all data

func (*LiteData) SetData

func (d *LiteData) SetData(data map[string]any)

SetData set all data

func (*LiteData) SetValue

func (d *LiteData) SetValue(key string, val any)

SetValue to data

func (*LiteData) StrValue

func (d *LiteData) StrValue(key string) string

StrValue get from data

func (*LiteData) Value

func (d *LiteData) Value(key string) any

Value get from data

type MapOptFunc

type MapOptFunc func(opt *MapOptions)

MapOptFunc define

type MapOptions

type MapOptions struct {
	TagName string
}

MapOptions struct

type SMap

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

SMap simple map[string]string struct.

type SetOptFunc

type SetOptFunc func(opt *SetOptions)

SetOptFunc define

type SetOptions

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
}

SetOptions for set values to struct

type TagParser

type TagParser struct {
	// TagNames want parsed tag names.
	TagNames []string
	// ValueFunc tag value parse func.
	ValueFunc TagValFunc
	// contains filtered or unexported fields
}

TagParser struct

func NewTagParser

func NewTagParser(tagNames ...string) *TagParser

NewTagParser instance

func (*TagParser) Info

func (p *TagParser) Info(field, tag string) (maputil.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) error

Parse an struct value

Example
package main

import (
	"fmt"
	"github.com/zhangyiming748/pretty"

	"github.com/zhangyiming748/pretty/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
	}

	u := &User{}
	p := structs.NewTagParser("json", "yaml", "default")
	pretty.MustOK(p.Parse(u))

	tags := p.Tags()
	pretty.P(tags)
	/*tags:
	map[string]maputil.SMap { #len=2
	  "Age": maputil.SMap { #len=3
	    "json": string("age"), #len=3
	    "yaml": string("age"), #len=3
	    "default": string("23"), #len=2
	  },
	  "Name": maputil.SMap { #len=3
	    "default": string("inhere"), #len=6
	    "json": string("name,omitempty"), #len=14
	    "yaml": string("name"), #len=4
	  },
	},
	*/

	pretty.P(p.Info("name", "json"))
	/*info:
	maputil.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 23
Example (ParseTagValueDefine)
package main

import (
	"fmt"
	"github.com/zhangyiming748/pretty"

	"github.com/zhangyiming748/pretty/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)

	pretty.MustOK(p.Parse(c))
	// pretty.P(p.Tags())
	/*
		map[string]maputil.SMap { #len=1
		  "Name": maputil.SMap { #len=1
		    "flag": string("set your name;false;INHERE;n"), #len=28
		  },
		},
	*/
	fmt.Println("tags:", p.Tags())

	info, _ := p.Info("Name", "flag")
	pretty.P(info)
	/*
		maputil.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) error

ParseType parse a struct type value

func (*TagParser) Tags

func (p *TagParser) Tags() map[string]maputil.SMap

Tags map data for struct fields

type TagValFunc

type TagValFunc func(field, tagVal string) (maputil.SMap, error)

TagValFunc handle func

func ParseTagValueDefine

func ParseTagValueDefine(sep string, defines []string) TagValFunc

ParseTagValueDefine 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

type Value struct {
	// V value
	V any
}

Value data store

func NewValue

func NewValue(val any) *Value

NewValue instance.

func (*Value) Bool

func (v *Value) Bool() bool

Bool value

func (*Value) Float64

func (v *Value) Float64() float64

Float64 value

func (*Value) Int

func (v *Value) Int() int

Int value get

func (*Value) Int64

func (v *Value) Int64() int64

Int64 value

func (*Value) IsEmpty

func (v *Value) IsEmpty() bool

IsEmpty 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

func (*Value) SplitToStrings

func (v *Value) SplitToStrings(sep ...string) (ss []string)

SplitToStrings split string value to strings

func (*Value) String

func (v *Value) String() string

String value

func (*Value) Strings

func (v *Value) Strings() (ss []string)

Strings value

func (*Value) Val

func (v *Value) Val() any

Val get

Jump to

Keyboard shortcuts

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