// Copyright 2018-2019 gf Author(https://github.com/gogf/gf). All Rights Reserved. // // This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. // Package gvar provides an universal variable type, like generics. package gvar import ( "encoding/json" "time" "github.com/gogf/gf/internal/empty" "github.com/gogf/gf/container/gtype" "github.com/gogf/gf/os/gtime" "github.com/gogf/gf/util/gconv" ) // Var is an universal variable type. type Var struct { value interface{} // Underlying value. safe bool // Concurrent safe or not. } // New creates and returns a new *Var with given . // The optional parameter specifies whether Var is used in concurrent-safety, // which is false in default. func New(value interface{}, safe ...bool) *Var { v := Create(value, safe...) return &v } // Create creates and returns a new Var with given . // The optional parameter specifies whether Var is used in concurrent-safety, // which is false in default. func Create(value interface{}, safe ...bool) Var { v := Var{} if len(safe) > 0 && !safe[0] { v.safe = true v.value = gtype.NewInterface(value) } else { v.value = value } return v } // Set sets to , and returns the old value. func (v *Var) Set(value interface{}) (old interface{}) { if v.safe { old = v.value.(*gtype.Interface).Set(value) } else { old = v.value v.value = value } return } // Val returns the current value of . func (v *Var) Val() interface{} { if v == nil { return nil } if v.safe { return v.value.(*gtype.Interface).Val() } return v.value } // Interface is alias of Val. func (v *Var) Interface() interface{} { return v.Val() } // IsNil checks whether is nil. func (v *Var) IsNil() bool { return v.Val() == nil } // IsEmpty checks whether is empty. func (v *Var) IsEmpty() bool { return empty.IsEmpty(v.Val()) } // Bytes converts and returns as []byte. func (v *Var) Bytes() []byte { return gconv.Bytes(v.Val()) } // String converts and returns as string. func (v *Var) String() string { return gconv.String(v.Val()) } // Bool converts and returns as bool. func (v *Var) Bool() bool { return gconv.Bool(v.Val()) } // Int converts and returns as int. func (v *Var) Int() int { return gconv.Int(v.Val()) } // Ints converts and returns as []int. func (v *Var) Ints() []int { return gconv.Ints(v.Val()) } // Int8 converts and returns as int8. func (v *Var) Int8() int8 { return gconv.Int8(v.Val()) } // Int16 converts and returns as int16. func (v *Var) Int16() int16 { return gconv.Int16(v.Val()) } // Int32 converts and returns as int32. func (v *Var) Int32() int32 { return gconv.Int32(v.Val()) } // Int64 converts and returns as int64. func (v *Var) Int64() int64 { return gconv.Int64(v.Val()) } // Uint converts and returns as uint. func (v *Var) Uint() uint { return gconv.Uint(v.Val()) } // Uints converts and returns as []uint. func (v *Var) Uints() []uint { return gconv.Uints(v.Val()) } // Uint8 converts and returns as uint8. func (v *Var) Uint8() uint8 { return gconv.Uint8(v.Val()) } // Uint16 converts and returns as uint16. func (v *Var) Uint16() uint16 { return gconv.Uint16(v.Val()) } // Uint32 converts and returns as uint32. func (v *Var) Uint32() uint32 { return gconv.Uint32(v.Val()) } // Uint64 converts and returns as uint64. func (v *Var) Uint64() uint64 { return gconv.Uint64(v.Val()) } // Float32 converts and returns as float32. func (v *Var) Float32() float32 { return gconv.Float32(v.Val()) } // Float64 converts and returns as float64. func (v *Var) Float64() float64 { return gconv.Float64(v.Val()) } // Floats converts and returns as []float64. func (v *Var) Floats() []float64 { return gconv.Floats(v.Val()) } // Strings converts and returns as []string. func (v *Var) Strings() []string { return gconv.Strings(v.Val()) } // Interfaces converts and returns as []interfaces{}. func (v *Var) Interfaces() []interface{} { return gconv.Interfaces(v.Val()) } // Slice is alias of Interfaces. func (v *Var) Slice() []interface{} { return v.Interfaces() } // Array is alias of Interfaces. func (v *Var) Array() []interface{} { return v.Interfaces() } // Vars converts and returns as []*Var. func (v *Var) Vars() []*Var { array := gconv.Interfaces(v.Val()) if len(array) == 0 { return nil } vars := make([]*Var, len(array)) for k, v := range array { vars[k] = New(v) } return vars } // Time converts and returns as time.Time. // The parameter specifies the format of the time string using gtime, // eg: Y-m-d H:i:s. func (v *Var) Time(format ...string) time.Time { return gconv.Time(v.Val(), format...) } // Duration converts and returns as time.Duration. // If value of is string, then it uses time.ParseDuration for conversion. func (v *Var) Duration() time.Duration { return gconv.Duration(v.Val()) } // GTime converts and returns as *gtime.Time. // The parameter specifies the format of the time string using gtime, // eg: Y-m-d H:i:s. func (v *Var) GTime(format ...string) *gtime.Time { return gconv.GTime(v.Val(), format...) } // Map converts to map[string]interface{}. func (v *Var) Map(tags ...string) map[string]interface{} { return gconv.Map(v.Val(), tags...) } // MapStrStr converts to map[string]string. func (v *Var) MapStrStr(tags ...string) map[string]string { m := v.Map(tags...) if len(m) > 0 { vMap := make(map[string]string) for k, v := range m { vMap[k] = gconv.String(v) } return vMap } return nil } // MapStrVar converts to map[string]*Var. func (v *Var) MapStrVar(tags ...string) map[string]*Var { m := v.Map(tags...) if len(m) > 0 { vMap := make(map[string]*Var) for k, v := range m { vMap[k] = New(v) } return vMap } return nil } // MapDeep converts to map[string]interface{} recursively. func (v *Var) MapDeep(tags ...string) map[string]interface{} { return gconv.MapDeep(v.Val(), tags...) } // MapDeep converts to map[string]string recursively. func (v *Var) MapStrStrDeep(tags ...string) map[string]string { m := v.MapDeep(tags...) if len(m) > 0 { vMap := make(map[string]string) for k, v := range m { vMap[k] = gconv.String(v) } return vMap } return nil } // MapStrVarDeep converts to map[string]*Var recursively. func (v *Var) MapStrVarDeep(tags ...string) map[string]*Var { m := v.MapDeep(tags...) if len(m) > 0 { vMap := make(map[string]*Var) for k, v := range m { vMap[k] = New(v) } return vMap } return nil } // Struct maps value of to . // The parameter should be a pointer to a struct instance. // The parameter is used to specify the key-to-attribute mapping rules. func (v *Var) Struct(pointer interface{}, mapping ...map[string]string) error { return gconv.Struct(v.Val(), pointer, mapping...) } // Struct maps value of to recursively. // The parameter should be a pointer to a struct instance. // The parameter is used to specify the key-to-attribute mapping rules. func (v *Var) StructDeep(pointer interface{}, mapping ...map[string]string) error { return gconv.StructDeep(v.Val(), pointer, mapping...) } // Structs converts to given struct slice. func (v *Var) Structs(pointer interface{}, mapping ...map[string]string) (err error) { return gconv.Structs(v.Val(), pointer, mapping...) } // StructsDeep converts to given struct slice recursively. func (v *Var) StructsDeep(pointer interface{}, mapping ...map[string]string) (err error) { return gconv.StructsDeep(v.Val(), pointer, mapping...) } // MapToMap converts map type variable to another map type variable . // The elements of should be type of struct/*struct. func (v *Var) MapToMap(pointer interface{}, mapping ...map[string]string) (err error) { return gconv.MapToMap(v.Val(), pointer, mapping...) } // MapToMapDeep recursively converts map type variable to another map type variable . // The elements of should be type of struct/*struct. func (v *Var) MapToMapDeep(pointer interface{}, mapping ...map[string]string) (err error) { return gconv.MapToMapDeep(v.Val(), pointer, mapping...) } // MapToMaps converts map type variable to another map type variable . // The elements of should be type of []struct/[]*struct. func (v *Var) MapToMaps(pointer interface{}, mapping ...map[string]string) (err error) { return gconv.MapToMaps(v.Val(), pointer, mapping...) } // MapToMapsDeep recursively converts map type variable to another map type variable . // The elements of should be type of []struct/[]*struct. func (v *Var) MapToMapsDeep(pointer interface{}, mapping ...map[string]string) (err error) { return gconv.MapToMapsDeep(v.Val(), pointer, mapping...) } // MarshalJSON implements the interface MarshalJSON for json.Marshal. func (v *Var) MarshalJSON() ([]byte, error) { return json.Marshal(v.Val()) } // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal. func (v *Var) UnmarshalJSON(b []byte) error { var i interface{} err := json.Unmarshal(b, &i) if err != nil { return err } v.Set(i) return nil }