Documentation
¶
Overview ¶
Package structs implements a generic interface for manipulating Go structs. The related API is powered and inspired from the Go reflection package.
Introduction ¶
It was initially developed to provide generic field getters and setters for any struct. It has grown into an generic abstraction layer to structs powered by the reflect package.
While not being particularly performant compared to other structs packages, it provides a "natural feel" API, convenience, flexibility and simpler alternative compared to using the reflect package directly.
Throughout the documentation, the t variable is assumed to be of type struct T. T has two fields: the first is a string field called "Property" and the second is a nested struct via a pointer called "Nested". While "Property" is set to value "Test", "Number" inside "Nested" is set to 123456.
type T struct{ Property string Nested *N } type N struct{ Number int } t := T{ Property: "Test", Nested: &N{Number: 123456}, }
NOTE: the same applies to all other variables subsequently declared.
Support ¶
The following input are supported throughout the package:
Types Description Example T a struct New(t) *T a pointer to a struct New(&t) []T a slice of struct New([]T{t}) *[]T a pointer to a slice of struct New(&[]T{t}) []*T a slice of pointers to struct New([]*T{&t})
NOTE: See the IndirectStruct method for details on the above scenarios.
Implementation ¶
There are two main ways to use for this package to manipulate structs. Either by using the objects and methods or by using helper functions.
Objects and methods: this approach requires calling of the New method first, which gives access to the API of the StructValue, StructField and StructFields objects.
Helper functions: A set of self-contained functions that hides internal implementations powered by the StructValue object, are all declared in the file called helpers.go.
The following table summarizes the above statements:
Usage Applicable Go Files Description Objects structs.go StructValue object field.go StructField object fields.go StructFields object rows.go StructRows object Helpers helpers.go Wrapper object functions
All objects in this package are linked to the main StructValue object. The relationships between each one of them are as follow:
-------------- | *StructValue |<----------------------------------------+ --+----------- | | | | --------------- | +---> Field(x) --->| *StructField |---> Parent ----->+ | --------------- | | | | --------------- | +---> Fields() --->| *StructFields |---> Parent() --->+ | --------------- | | | | --------------- | +---> Rows() ----->| *StructRows |---> Parent ----->+ ---------------
NOTE: For an exhaustive illustration of package capabilities, please refer to the following file: https://github.com/roninzo/structs/example_test.go.
StructValue ¶
The StructValue object is the starting point for manipulating structs using objects and methods. To initialize the StructValue object, make use of the New method followed by handling any potential error encountered in this process.
Example:
s, err := structs.New(&t) if err != nil { return err }
From there, several methods provides information about the struct.
Example:
fmt.Printf("t has %d field(s)\n", s.NumField()) // Output: // t has 2 field(s)
NOTE: When possible, all object method names were inspired from the reflect package, trying to reduce the learning curve.
Example:
if s.CanSet() { fmt.Println("t is modifiable") } // Output: // t is modifiable
The StructValue object is also the gateway to the other two objects declared in this package: StructField and StructFields.
Examples:
f := s.Field("Property") // f is a StructField object fields := s.Fields() // fields is a StructFields object
StructField ¶
The StructField object represents one field in the struct, and provides getters and setters methods.
Before reading data out of struct fields generically, it is recommended to get extra information about the struct field. This is useful if the type of the field is not known at runtime.
Example:
f := s.Field("Property") if f.CanString() { fmt.Printf("Property was equal to %q\n", s.String()) if f.CanSet() { err := f.SetString("Verified") if err != nil { return err } fmt.Printf("Property is now equal to %q\n", s.String()) } } // Output: // Property was equal to 'Test' // Property is now equal to 'Verified'
However, if nested struct are present inside t, sub-fields are not made available directly. This means that nested structs must be loaded explicitly with the Struct method.
Example:
f := s.Field("Nested") if err := s.Err(); err != nil { return err } if f.CanStruct() { f = f.Struct().Field("Number") if f.CanInt() { fmt.Printf("Number was equal to %d\n", f.Int()) if f.CanSet() { err := f.SetInt(654321) if err != nil { return err } fmt.Printf("Number is now equal to %d\n", f.Int()) } } } // Output: // Number was equal to 123456 // Number is now equal to 654321
StructFields ¶
The StructFields object represents all the fields in the struct. Its main purpose at the moment, is to loop through StructField objects in a "for range" loop.
Example:
for _, f := range s.Fields() { fmt.Printf("struct field name is: %s\n", f.Name()) } // Output: // struct field name is: Property // struct field name is: Nested
The other purpose, is to return all struct filed names:
Example:
names := s.Fields().Names() fmt.Printf("struct field names are: %v\n", names) // Output: // struct field names are: [Property Nested]
StructRows ¶
The StructRows object represents the slice of structs and mostly follows the database/sql API. Its main purpose is to loop through elements of a submitted slice of structs. Each of those elements can then be manipulated in the same manner as the StructValue.
Example:
s, err := structs.New([]*T{&t}) if err != nil { return err } rows, err := s.Rows() if err != nil { return err } defer rows.Close() for rows.Next() { f := rows.Field("Property") f.Set(f.String() + "s") // adds an "s" to the Property field fmt.Printf("%s: %s.\n", f.Name(), f.String()) } // Output: // Property: Tests.
Helper functions ¶
The helper methods in the helpers.go provide advanced functions for transforming structs or wrap StructValue object functionalities.
Examples:
clone, err := structs.Clone(&t) if err != nil { return err } t2, ok := clone.(*T) if ok { same := structs.Compare(t2, &t) if same { fmt.Println("t and t2 are the same") } t2.Property = "Cloned" if err != nil { return err } same = structs.Compare(t2, &t) if !same { fmt.Println("t and t2 are now different") } } // Output: // t and t2 are the same // t and t2 are now different
Index ¶
- Constants
- Variables
- func Clone(src interface{}) (interface{}, error)
- func Compare(dest, src interface{}) bool
- func Copy(dest, src interface{}) error
- func Defaults(dest interface{}) error
- func Diff(dest, src interface{}) (map[string]interface{}, error)
- func Forward(dest, src interface{}) error
- func MapFunc(dest interface{}, handler func(reflect.Value) error) (interface{}, error)
- func Name(dest interface{}) (string, error)
- func Names(dest interface{}) ([]string, error)
- func Replace(dest, old, new interface{}, n int) (interface{}, error)
- func ScanFromMap(dest interface{}, row map[string]interface{}, mapping map[string]string) error
- func Sprint(dest interface{}) string
- func SprintCompact(dest interface{}) string
- func Transpose(dest, src interface{}) error
- func Unmarhsal(src interface{}, dest *map[string]interface{}) error
- type StructField
- func (f *StructField) AssignableTo(x reflect.Value) bool
- func (f *StructField) Bool() bool
- func (f *StructField) Bytes() []byte
- func (f *StructField) CanBool() bool
- func (f *StructField) CanBytes() bool
- func (f *StructField) CanComplex() bool
- func (f *StructField) CanDuration() bool
- func (f *StructField) CanError() bool
- func (f *StructField) CanFloat() bool
- func (f *StructField) CanInt() bool
- func (f *StructField) CanInterface() bool
- func (f *StructField) CanMap() bool
- func (f *StructField) CanNil() bool
- func (f *StructField) CanPtr() bool
- func (f *StructField) CanSet() bool
- func (f *StructField) CanSlice() bool
- func (f *StructField) CanString() bool
- func (f *StructField) CanStruct() bool
- func (f *StructField) CanTime() bool
- func (f *StructField) CanUint() bool
- func (f *StructField) Complex() complex128
- func (f *StructField) Default() string
- func (f *StructField) Duration() time.Duration
- func (f *StructField) Equal(x *StructField) bool
- func (f *StructField) Error() error
- func (f *StructField) Float() float64
- func (f *StructField) FullName() (n string)
- func (f *StructField) Get() interface{}
- func (f *StructField) Index() int
- func (f *StructField) Indirect() reflect.Value
- func (f *StructField) IndirectType() reflect.Type
- func (f *StructField) Int() int64
- func (f *StructField) Interface() interface{}
- func (f *StructField) IsAnonymous() bool
- func (f *StructField) IsEmbedded() bool
- func (f *StructField) IsExported() bool
- func (f *StructField) IsHidden() bool
- func (f *StructField) IsNil() bool
- func (f *StructField) IsValid() bool
- func (f *StructField) IsZero() bool
- func (f *StructField) Kind() reflect.Kind
- func (f *StructField) Name() string
- func (f *StructField) NameJson() string
- func (f *StructField) Set(dest interface{}) error
- func (f *StructField) SetBool(x bool)
- func (f *StructField) SetBytes(x []byte)
- func (f *StructField) SetComplex(x complex128)
- func (f *StructField) SetDuration(x time.Duration)
- func (f *StructField) SetError(x error)
- func (f *StructField) SetFloat(x float64)
- func (f *StructField) SetInt(x int64)
- func (f *StructField) SetInterface(x interface{})
- func (f *StructField) SetNil() error
- func (f *StructField) SetString(x string)
- func (f *StructField) SetStruct(x *StructValue)
- func (f *StructField) SetTime(x time.Time)
- func (f *StructField) SetUint(x uint64)
- func (f *StructField) SetZero() error
- func (f *StructField) String() string
- func (f *StructField) Struct() *StructValue
- func (f *StructField) Tag(key string) (string, bool)
- func (f *StructField) Time() time.Time
- func (f *StructField) Type() reflect.Type
- func (f *StructField) Uint() uint64
- func (f *StructField) Value() reflect.Value
- func (f *StructField) Zero() reflect.Value
- type StructFields
- type StructRows
- type StructValue
- func (s *StructValue) CanSet() bool
- func (s *StructValue) Contains(dest interface{}) int
- func (s *StructValue) Debug() string
- func (s *StructValue) Defaults() error
- func (s *StructValue) Diff(c *StructValue) (map[string]interface{}, error)
- func (s *StructValue) Err() (err error)
- func (s *StructValue) Field(dest interface{}) *StructField
- func (s *StructValue) Fields() StructFields
- func (s *StructValue) FindStruct(name string) *StructValue
- func (s *StructValue) Forward(c *StructValue) error
- func (s *StructValue) FullName() string
- func (s *StructValue) HasField(dest interface{}, arg interface{}) (bool, error)
- func (s *StructValue) HasNested() bool
- func (s *StructValue) HasZero() bool
- func (s *StructValue) Import(c *StructValue) error
- func (s *StructValue) IndirectValues() (values []reflect.Value)
- func (s *StructValue) IsNested() bool
- func (s *StructValue) IsValid() bool
- func (s *StructValue) IsZero() bool
- func (s *StructValue) Kind() reflect.Kind
- func (s *StructValue) MapFunc(handler func(reflect.Value) error) (*StructValue, error)
- func (s *StructValue) Multiple() bool
- func (s *StructValue) Name() string
- func (s *StructValue) NumField() int
- func (s *StructValue) Path() string
- func (s *StructValue) Rows() (*StructRows, error)
- func (s *StructValue) Sprint() string
- func (s *StructValue) Type() reflect.Type
- func (s *StructValue) Value() (v reflect.Value)
- func (s *StructValue) Values() (values []reflect.Value)
- Bugs
Examples ¶
- New
- StructField.Bool
- StructField.Bytes
- StructField.CanBool
- StructField.CanBytes
- StructField.CanComplex
- StructField.CanDuration
- StructField.CanError
- StructField.CanFloat
- StructField.CanInt
- StructField.CanInterface
- StructField.CanSet
- StructField.CanString
- StructField.CanStruct
- StructField.CanTime
- StructField.CanUint
- StructField.Complex
- StructField.Duration
- StructField.Equal
- StructField.Equal (Different)
- StructField.Equal (PointerFields)
- StructField.Error
- StructField.Float
- StructField.FullName
- StructField.Get
- StructField.Index
- StructField.Indirect
- StructField.Int
- StructField.Interface
- StructField.IsAnonymous
- StructField.IsEmbedded
- StructField.IsExported
- StructField.IsHidden
- StructField.IsNil
- StructField.IsValid
- StructField.IsZero
- StructField.Kind
- StructField.Name
- StructField.Set
- StructField.Set (ValueToNil)
- StructField.Set (ValueToValue)
- StructField.Set (ValueToZero)
- StructField.Set (ZeroToValue)
- StructField.SetBool
- StructField.SetBytes
- StructField.SetComplex
- StructField.SetDuration
- StructField.SetError
- StructField.SetFloat
- StructField.SetInt
- StructField.SetInterface
- StructField.SetString
- StructField.SetStruct
- StructField.SetTime
- StructField.SetUint
- StructField.SetZero
- StructField.String
- StructField.Struct
- StructField.Tag
- StructField.Time
- StructField.Type
- StructField.Uint
- StructField.Value
- StructField.Zero
- StructFields.Names
- StructRows.Close
- StructRows.Columns
- StructRows.Err
- StructRows.Index
- StructRows.Len
- StructRows.MaxRow
- StructRows.Next
- StructValue.CanSet
- StructValue.Diff
- StructValue.Field
- StructValue.Fields
- StructValue.FindStruct
- StructValue.FullName
- StructValue.HasNested
- StructValue.HasZero
- StructValue.IndirectValues
- StructValue.IsNested
- StructValue.IsValid
- StructValue.IsZero
- StructValue.Kind
- StructValue.Multiple
- StructValue.Name
- StructValue.NumField
- StructValue.Path
- StructValue.Rows
- StructValue.Rows (Empty)
- StructValue.Rows (NotMultiple)
- StructValue.Sprint
- StructValue.Type
- StructValue.Value
- StructValue.Values
Constants ¶
const ( OutOfRange = -1 ReplaceAll = -1 )
Variables ¶
var ( ErrNotExported = errors.New("struct field is not exported") ErrNotSettable = errors.New("struct field is not settable") ErrNotNillable = errors.New("struct field is not nillable") ErrNoStruct = errors.New("struct not found") ErrNoStructs = errors.New("structs not found") ErrNoField = errors.New("struct field not found") ErrNoFields = errors.New("struct fields not found") ErrNoRow = errors.New("struct row not found") ErrNoRows = errors.New("struct rows not found") ErrRowsClosed = errors.New("struct rows are closed") ErrNotReplaced = errors.New("struct field old and new value types does not match") // could not replace value in struct )
Functions ¶
func Clone ¶
func Clone(src interface{}) (interface{}, error)
Clone returns a copy from a struct out of nothing.
// ctx will be the context error returned // by this func if anything goes wrong ctx := "could not clone struct" // // Source interface must be valid struct for this to work // Target dest will be the recipient for a copy of src s1, err := New(src)
if err != nil { return nil, errors.Wrap(err, ctx) }
t := s1.Type() dest := reflect.New(t).Interface() s2, err := New(dest)
if err != nil { return nil, errors.Wrap(err, ctx) }
// // ctx content can now now be improved ctx = fmt.Sprintf("could not clone struct %q", s1.Name()) // // Target struct must be editable
if !s2.CanSet() { return nil, errors.Wrap(errors.Errorf("cannot edit struct %s", s2.Name()), ctx) }
// // Target must be singular of struct, not multiple
if s2.Multiple() { return nil, errors.Wrap(errors.Errorf("source is a slice of struct %s", s2.Name()), ctx) }
err = s2.Import(s1) return dest, err
func Compare ¶
func Compare(dest, src interface{}) bool
Compare returns dest boolean comparing two structs.
func Copy ¶
func Copy(dest, src interface{}) error
Copy makes a copy, for instance, of a struct pointer. Do the copy "manually", e.g. create a new struct and copy the fields, where pointers or slices/maps/channels/etc must be duplicated manually, in a recursive manner.
Resources: https://stackoverflow.com/questions/50269322/how-to-copy-struct-and-dereference-all-pointers
// ctx will be the context error returned // by this func if anything goes wrong ctx := "could not copy data between two structs" // // Both interfaces must be valid structs for this to work s1, err := New(src)
if err != nil { return errors.Wrap(err, ctx) }
s2, err := New(dest)
if err != nil { return errors.Wrap(err, ctx) }
// // ctx content can now now be improved ctx = fmt.Sprintf("could not copy data between two %q structs", s1.Name()) // // StructValue names must be the same
if s1.Name() != s2.Name() { return errors.Wrap(errors.Errorf("target struct name is invalid: want: %q, got: %q", s1.Name(), s2.Name()), ctx) }
// // Target struct must be editable
if !s2.CanSet() { return errors.Wrap(errors.Errorf("cannot edit struct %s", s2.Name()), ctx) }
// // Both interfaces must be singulars of struct, not multiples
if s1.Multiple() { return errors.Wrap(errors.Errorf("source is a slice of struct %s", s1.Name()), ctx) }
if s2.Multiple() { return errors.Wrap(errors.Errorf("target is a slice of struct %s", s2.Name()), ctx) }
return s2.Import(s1)
func Diff ¶ added in v1.0.3
Diff returns differences between two structs. Where diffs stores values from dest indexed by column names.
func Forward ¶
func Forward(dest, src interface{}) error
Forward copies only non-zero values between two structs, i.e. from src to dest interface.
func MapFunc ¶
MapFunc returns a copy of the StructValue s with all its fields modified according to the mapping function handler.
If mapping returns a negative value, the character is dropped from the byte slice with no replacement. The characters in s and the output are interpreted as UTF-8-encoded code points.
BUG(roninzo): the MapFunc method argument dest is also changed. should that be the case?
func Name ¶
Name returns the structs's type name within its package. It returns an empty string for unnamed types. It returns an error if s's kind is not struct.
func Names ¶
Names returns a slice of field names. For more info refer to StructValue types Names() method. It returns an error if s's kind is not struct.
func Replace ¶
Replace returns a copy of the struct dest with the first n non-overlapping instance of old replaced by new.
Counts how many replacing to do until n. if n = -1, then replace all.
func ScanFromMap ¶ added in v1.0.2
ScanFromMap trusted source maps of string to interface{} row into Go struct dest.
Optionally, a mapping argument can be provided if the column names are different between dest and row. That argument is a key-value pair of strings where key is the column name in dest and value the column name in row.
func Sprint ¶ added in v1.0.1
func Sprint(dest interface{}) string
Sprint returns a MarshalIndent string.
BUG(roninzo): Sprint uses json marshaling which does not support complex types (complex64/complex128).
func SprintCompact ¶ added in v1.0.3
func SprintCompact(dest interface{}) string
Sprint returns a Marshal one-line string (without indenting).
Types ¶
type StructField ¶
type StructField struct { Parent *StructValue // field's own struct reference. // contains filtered or unexported fields }
StructField represents a single struct field that encapsulates high level functions around the field.
func (*StructField) AssignableTo ¶
func (f *StructField) AssignableTo(x reflect.Value) bool
AssignableTo reports whether a field value is assignable to reflect Value x.
NOTE: case utils.CanInterface(v) && utils.CanInterface(x):
no need; x came from interface{} dest
func (*StructField) Bool ¶
func (f *StructField) Bool() bool
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Enabled") if f1.CanBool() { fmt.Printf("Bool: %v\n", f1.Bool()) } if f2.CanBool() { fmt.Printf("Bool: %v\n", f2.Bool()) } }
Output: Bool: true
func (*StructField) Bytes ¶
func (f *StructField) Bytes() []byte
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Stream []byte `json:"stream,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Stream: []byte("Hello world"), Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Stream") if f1.CanBytes() { fmt.Printf("Bytes: %v.\n", f1.Bytes()) } if f2.CanBytes() { b := f2.Bytes() fmt.Printf("Bytes: %v.\n", b) fmt.Printf("BytesString: %v.\n", string(b)) } }
Output: Bytes: [72 101 108 108 111 32 119 111 114 108 100]. BytesString: Hello world.
func (*StructField) CanBool ¶
func (f *StructField) CanBool() bool
Example ¶
package main import ( "fmt" "time" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` ChangedAt time.Time `json:"changed_at,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, ChangedAt: time.Date(2021, time.August, 3, 16, 44, 46, 0, time.UTC), Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Enabled") fmt.Printf("CanBool: %v\n", f1.CanBool()) fmt.Printf("CanBool: %v\n", f2.CanBool()) }
Output: CanBool: false CanBool: true
func (*StructField) CanBytes ¶
func (f *StructField) CanBytes() bool
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Stream []byte `json:"stream,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Stream: []byte("Hello world"), Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Stream") fmt.Printf("CanBytes: %v\n", f1.CanBytes()) fmt.Printf("CanBytes: %v\n", f2.CanBytes()) }
Output: CanBytes: false CanBytes: true
func (*StructField) CanComplex ¶
func (f *StructField) CanComplex() bool
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Complex complex128 `json:"complex,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Complex: complex(23, 31), Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Complex") fmt.Printf("CanComplex: %v\n", f1.CanComplex()) fmt.Printf("CanComplex: %v\n", f2.CanComplex()) }
Output: CanComplex: false CanComplex: true
func (*StructField) CanDuration ¶
func (f *StructField) CanDuration() bool
Example ¶
package main import ( "fmt" "time" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` TimeOut time.Duration `json:"time_out,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, TimeOut: 5 * time.Second, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("TimeOut") fmt.Printf("CanDuration: %v\n", f1.CanDuration()) fmt.Printf("CanDuration: %v\n", f2.CanDuration()) }
Output: CanDuration: false CanDuration: true
func (*StructField) CanError ¶
func (f *StructField) CanError() bool
Example ¶
package main import ( "fmt" "github.com/pkg/errors" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Err error `json:"err,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Err: errors.New("failed"), Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Err") fmt.Printf("CanError: %v\n", f1.CanError()) fmt.Printf("CanError: %v\n", f2.CanError()) }
Output: CanError: false CanError: true
func (*StructField) CanFloat ¶
func (f *StructField) CanFloat() bool
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Price float32 `json:"price,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Price: 10.50, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Price") fmt.Printf("CanFloat: %v\n", f1.CanFloat()) fmt.Printf("CanFloat: %v\n", f2.CanFloat()) }
Output: CanFloat: false CanFloat: true
func (*StructField) CanInt ¶
func (f *StructField) CanInt() bool
Example ¶
package main import ( "fmt" "time" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID int `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` ChangedAt time.Time `json:"changed_at,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, ChangedAt: time.Date(2021, time.August, 3, 16, 44, 46, 0, time.UTC), Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("ID") fmt.Printf("CanInt: %v\n", f1.CanInt()) fmt.Printf("CanInt: %v\n", f2.CanInt()) }
Output: CanInt: false CanInt: true
func (*StructField) CanInterface ¶
func (f *StructField) CanInterface() bool
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Anything interface{} `json:"anything,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Anything: 654321, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Anything") fmt.Printf("CanInterface: %v\n", f1.CanInterface()) fmt.Printf("CanInterface: %v\n", f2.CanInterface()) }
Output: CanInterface: false CanInterface: true
func (*StructField) CanMap ¶ added in v1.0.5
func (f *StructField) CanMap() bool
func (*StructField) CanNil ¶
func (f *StructField) CanNil() bool
func (*StructField) CanPtr ¶
func (f *StructField) CanPtr() bool
func (*StructField) CanSet ¶
func (f *StructField) CanSet() bool
Interface returns true if underlying value of the field is modifiable.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Program struct { Name string `json:"name,omitempty"` } type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` Program Program `json:"program,omitempty"` } program := Program{ Name: "Apache", } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", Program: program, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f := s.Field(0) fmt.Printf("CanSet: %v\n", f.CanSet()) s, err = structs.New(server) if err != nil { fmt.Printf("Error: %v\n", err) } f = s.Field(0) fmt.Printf("CanSet: %v\n", f.CanSet()) }
Output: CanSet: true CanSet: false
func (*StructField) CanSlice ¶ added in v1.0.5
func (f *StructField) CanSlice() bool
func (*StructField) CanString ¶
func (f *StructField) CanString() bool
Example ¶
package main import ( "fmt" "time" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` ChangedAt time.Time `json:"changed_at,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, ChangedAt: time.Date(2021, time.August, 3, 16, 44, 46, 0, time.UTC), Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("ChangedAt") fmt.Printf("CanString: %v\n", f1.CanString()) fmt.Printf("CanString: %v\n", f2.CanString()) }
Output: CanString: true CanString: false
func (*StructField) CanStruct ¶
func (f *StructField) CanStruct() bool
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Program struct { Name string `json:"name,omitempty"` } type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` Program Program `json:"program,omitempty"` } program := Program{ Name: "Apache", } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", Program: program, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Program") fmt.Printf("CanStruct: %v\n", f1.CanStruct()) fmt.Printf("CanStruct: %v\n", f2.CanStruct()) }
Output: CanStruct: false CanStruct: true
func (*StructField) CanTime ¶
func (f *StructField) CanTime() bool
Example ¶
package main import ( "fmt" "time" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` ChangedAt time.Time `json:"changed_at,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, ChangedAt: time.Date(2021, time.August, 3, 16, 44, 46, 0, time.UTC), Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("ChangedAt") fmt.Printf("CanTime: %v\n", f1.CanTime()) fmt.Printf("CanTime: %v\n", f2.CanTime()) }
Output: CanTime: false CanTime: true
func (*StructField) CanUint ¶
func (f *StructField) CanUint() bool
Example ¶
package main import ( "fmt" "time" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` ChangedAt time.Time `json:"changed_at,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, ChangedAt: time.Date(2021, time.August, 3, 16, 44, 46, 0, time.UTC), Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("ID") fmt.Printf("CanUint: %v\n", f1.CanUint()) fmt.Printf("CanUint: %v\n", f2.CanUint()) }
Output: CanUint: false CanUint: true
func (*StructField) Complex ¶
func (f *StructField) Complex() complex128
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Complex complex128 `json:"complex,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Complex: complex(22, 50), Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Complex") if f1.CanComplex() { fmt.Printf("Complex: %v.\n", f1.Complex()) } if f2.CanComplex() { fmt.Printf("Complex: %v.\n", f2.Complex()) } }
Output: Complex: (22+50i).
func (*StructField) Default ¶ added in v1.0.4
func (f *StructField) Default() string
Default returns returns the string default value of StructField defined in its related default struct tag, else returns empty string.
func (*StructField) Duration ¶
func (f *StructField) Duration() time.Duration
Example ¶
package main import ( "fmt" "time" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` TimeOut time.Duration `json:"time_out,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, TimeOut: 5 * time.Second, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("TimeOut") if f1.CanDuration() { fmt.Printf("Duration: %v\n", f1.Duration()) } if f2.CanDuration() { fmt.Printf("Duration: %v\n", f2.Duration()) } }
Output: Duration: 5s
func (*StructField) Equal ¶
func (f *StructField) Equal(x *StructField) bool
Equal compares field value with reflect value argument and returns true
Example ¶
package main import ( "fmt" "time" "github.com/pkg/errors" "github.com/roninzo/structs" ) func main() { type Program struct { Name string `json:"name,omitempty"` } program1 := Program{Name: "Apache"} program2 := Program{Name: "Apache"} type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Err error `json:"err,omitempty"` ChangedAt time.Time `json:"changed_at,omitempty"` TimeOut time.Duration `json:"time_out,omitempty"` Count int `json:"count,omitempty"` Price float32 `json:"price,omitempty"` Complex complex128 `json:"complex,omitempty"` Stream []byte `json:"stream,omitempty"` Anything interface{} `json:"anything,omitempty"` Program *Program `json:"program,omitempty"` Password string `json:"-"` unexported bool } server1 := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Err: errors.New("rows not found"), ChangedAt: time.Date(2021, time.August, 3, 16, 44, 46, 0, time.UTC), TimeOut: 5 * time.Second, Count: 8, Price: 1922.50, Complex: complex(22, 50), Stream: []byte("Hello world"), Anything: 654321, Program: &program1, Password: "abcdefg", unexported: true, } server2 := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Err: errors.New("rows not found"), ChangedAt: time.Date(2021, time.August, 3, 16, 44, 46, 0, time.UTC), TimeOut: 5 * time.Second, Count: 8, Price: 1922.50, Complex: complex(22, 50), Stream: []byte("Hello world"), Anything: 654321, Program: &program2, Password: "abcdefg", unexported: true, } s1, err := structs.New(&server1) if err != nil { fmt.Printf("Error: %v\n", err) } s2, err := structs.New(&server2) if err != nil { fmt.Printf("Error: %v\n", err) } for i, f1 := range s1.Fields() { f2 := s2.Field(i) fmt.Printf("Equal: %v.\n", f1.Equal(f2)) } }
Output: Equal: true. Equal: true. Equal: true. Equal: true. Equal: true. Equal: true. Equal: true. Equal: true. Equal: true. Equal: true. Equal: true. Equal: true. Equal: true. Equal: false.
Example (Different) ¶
package main import ( "fmt" "time" "github.com/pkg/errors" "github.com/roninzo/structs" ) func main() { type Program struct { Name string `json:"name,omitempty"` } program1 := Program{Name: "Apache"} program2 := Program{Name: "Microsoft IIS"} type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Err error `json:"err,omitempty"` ChangedAt time.Time `json:"changed_at,omitempty"` TimeOut time.Duration `json:"time_out,omitempty"` Count int `json:"count,omitempty"` Price float32 `json:"price,omitempty"` Complex complex128 `json:"complex,omitempty"` Stream []byte `json:"stream,omitempty"` Anything interface{} `json:"anything,omitempty"` Program *Program `json:"program,omitempty"` Password string `json:"-"` unexported bool } server1 := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Err: errors.New("rows not found"), ChangedAt: time.Date(2021, time.August, 3, 16, 44, 46, 0, time.UTC), TimeOut: 5 * time.Second, Count: 8, Price: 1922.50, Complex: complex(22, 50), Stream: []byte("Hello world"), Anything: 654321, Program: &program1, Password: "abcdefg", unexported: true, } server2 := Server{ Name: "ozninoR", ID: 654321, Enabled: false, Err: errors.New("not compliant"), ChangedAt: time.Date(2021, time.August, 31, 14, 11, 11, 0, time.UTC), TimeOut: 30 * time.Second, Count: 3, Price: 7622.50, Complex: complex(-67, -42), Stream: []byte("Bye bye world"), Anything: 123456, Program: &program2, Password: "gfedcba", unexported: false, } s1, err := structs.New(&server1) if err != nil { fmt.Printf("Error: %v\n", err) } s2, err := structs.New(&server2) if err != nil { fmt.Printf("Error: %v\n", err) } for i, f1 := range s1.Fields() { f2 := s2.Field(i) fmt.Printf("Equal: %v.\n", f1.Equal(f2)) } }
Output: Equal: false. Equal: false. Equal: false. Equal: false. Equal: false. Equal: false. Equal: false. Equal: false. Equal: false. Equal: false. Equal: false. Equal: false. Equal: false. Equal: false.
Example (PointerFields) ¶
package main import ( "fmt" "time" "github.com/roninzo/pointers" "github.com/roninzo/structs" ) func main() { type Program struct { Name *string `json:"name,omitempty"` } type Server struct { Name *string `json:"name,omitempty"` ID *uint `json:"id,omitempty"` Enabled *bool `json:"enabled,omitempty"` Err *string `json:"err,omitempty"` // *error ChangedAt *time.Time `json:"changed_at,omitempty"` // FIXME: should not be different from clone TimeOut *time.Duration `json:"time_out,omitempty"` Count *int `json:"count,omitempty"` Price *float32 `json:"price,omitempty"` Stream *[]byte `json:"stream,omitempty"` Complex *complex128 `json:"complex,omitempty"` Anything interface{} `json:"anything,omitempty"` Program *Program `json:"program,omitempty"` Password *string `json:"-"` unexported *bool } program1 := Program{ Name: pointers.String("Apache"), } server1 := Server{ Name: pointers.String("Roninzo"), ID: pointers.Uint(123456), Enabled: pointers.Bool(true), Err: pointers.String("rows not found"), // pointers.Error(errors.New("rows not found")), ChangedAt: pointers.Time(time.Date(2021, time.August, 3, 16, 44, 46, 0, time.UTC)), TimeOut: pointers.Duration(5 * time.Second), Count: pointers.Int(8), Price: pointers.Float32(1922.50), Stream: pointers.Bytes([]byte("Hello world")), Complex: pointers.Complex128(complex(22, 50)), Anything: "test", Program: &program1, Password: pointers.String("abcdefg"), unexported: pointers.Bool(true), } program2 := Program{ Name: pointers.String("Microsoft IIS"), } server2 := Server{ Name: pointers.String("ozninoR"), ID: pointers.Uint(654321), Enabled: pointers.Bool(false), Err: pointers.String("not compliant"), // pointers.Error(errors.New("not compliant")), ChangedAt: pointers.Time(time.Date(2021, time.August, 31, 14, 11, 11, 0, time.UTC)), TimeOut: pointers.Duration(30 * time.Second), Count: pointers.Int(3), Price: pointers.Float32(7022.50), Stream: pointers.Bytes([]byte("Bye bye world")), Complex: pointers.Complex128(complex(99, 12)), Anything: 654321, Program: &program2, Password: pointers.String("gfedcba"), unexported: pointers.Bool(false), } // backup <- server1 via cloning clone, err := structs.Clone(&server1) if err != nil { fmt.Printf("Clone[Error]: %v.\n", err) return } backup, ok := clone.(*Server) if !ok { fmt.Printf("TypeAssertion[Error]: %v.\n", err) return } s1, err := structs.New(&server1) if err != nil { fmt.Printf("New1[Error]: %v.\n", err) return } s2, err := structs.New(backup) if err != nil { fmt.Printf("New2[Error]: %v.\n", err) return } fmt.Println("Compare server1 and backup (equal)") for i, f1 := range s1.Fields() { f2 := s2.Field(i) fmt.Printf("[%d]Equal: %v. (%s)\n", i, f1.Equal(f2), f2.Name()) } s2, err = structs.New(&server2) if err != nil { fmt.Printf("New3[Error]: %v.\n", err) return } fmt.Println("Compare server1 and server2 (different)") for i, f1 := range s1.Fields() { f2 := s2.Field(i) fmt.Printf("[%d]Equal: %v. (%s)\n", i, f1.Equal(f2), f2.Name()) } }
Output: Compare server1 and backup (equal) [0]Equal: true. (Name) [1]Equal: true. (ID) [2]Equal: true. (Enabled) [3]Equal: true. (Err) [4]Equal: false. (ChangedAt) [5]Equal: true. (TimeOut) [6]Equal: true. (Count) [7]Equal: true. (Price) [8]Equal: true. (Stream) [9]Equal: true. (Complex) [10]Equal: true. (Anything) [11]Equal: true. (Program) [12]Equal: true. (Password) [13]Equal: false. (unexported) Compare server1 and server2 (different) [0]Equal: false. (Name) [1]Equal: false. (ID) [2]Equal: false. (Enabled) [3]Equal: false. (Err) [4]Equal: false. (ChangedAt) [5]Equal: false. (TimeOut) [6]Equal: false. (Count) [7]Equal: false. (Price) [8]Equal: false. (Stream) [9]Equal: false. (Complex) [10]Equal: false. (Anything) [11]Equal: false. (Program) [12]Equal: false. (Password) [13]Equal: false. (unexported)
func (*StructField) Error ¶
func (f *StructField) Error() error
Example ¶
package main import ( "fmt" "github.com/pkg/errors" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Err error `json:"err,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Err: errors.New("failed"), Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Err") if f1.CanError() { fmt.Printf("Error: %v\n", f1.Error()) } if f2.CanError() { fmt.Printf("Error: %v\n", f2.Error()) } }
Output: Error: failed
func (*StructField) Float ¶
func (f *StructField) Float() float64
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Price float32 `json:"price,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Price: 22.50, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Price") if f1.CanFloat() { fmt.Printf("Float: %v\n", f1.Float()) } if f2.CanFloat() { fmt.Printf("Float: %v\n", f2.Float()) } }
Output: Float: 22.5
func (*StructField) FullName ¶ added in v1.0.5
func (f *StructField) FullName() (n string)
FullName is similar to the Name method, except that it includes its related struct names all the way to the top level struct (in a dot separated string).
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Program struct { Name string `json:"name,omitempty"` } type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` Program *Program `json:"program,omitempty"` } program := Program{ Name: "Apache", } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", Program: &program, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.FindStruct("Program").Field(0) fmt.Printf("FullName: %v\n", f1.FullName()) fmt.Printf("FullName: %v\n", f2.FullName()) }
Output: FullName: Server.Name FullName: Server.Program.Name
func (*StructField) Get ¶
func (f *StructField) Get() interface{}
Get returns the value of the field as interface. reflect.Struct, reflect.Slice, reflect.Array, reflect.Map, reflect.Interface, reflect.Func, reflect.Chan, reflect.Uintptr, reflect.UnsafePointer, reflect.Invalid Unexported struct fields will be neglected.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Count") f3 := s.Field("unexported") f4 := s.Field("Password") f5 := s.Field("Undeclared") err = s.Err() if f5 == nil && err != nil { fmt.Printf("Error: %v.\n", err) } v1 := f1.Get() v2 := f2.Get() v3 := f3.Get() v4 := f4.Get() fmt.Printf("Value %-11s: %v.\n", f1.Name(), f1.Value()) fmt.Printf("Value %-11s: %v.\n", f2.Name(), f2.Value()) fmt.Printf("Value %-11s: %v.\n", f3.Name(), f3.Value()) fmt.Printf("Value %-11s: %v.\n", f4.Name(), f4.Value()) fmt.Printf("Get %-11s: %v.\n", f1.Name(), v1) fmt.Printf("Get %-11s: %v.\n", f2.Name(), v2) fmt.Printf("Get %-11s: %v.\n", f3.Name(), v3) fmt.Printf("Get %-11s: %v.\n", f4.Name(), v4) }
Output: Error: invalid field name Undeclared. Value Name : Roninzo. Value Count : 0. Value unexported : false. Value Password : abcdefg. Get Name : Roninzo. Get Count : 0. Get unexported : <nil>. Get Password : abcdefg.
func (*StructField) Index ¶
func (f *StructField) Index() int
Index returns the struct index of the given field. If field is not valid, Index returns the OutOfRange constant, i.e. -1.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Count") fmt.Printf("Index: %v\n", f1.Index()) fmt.Printf("Index: %v\n", f2.Index()) }
Output: Index: 0 Index: 3
func (*StructField) Indirect ¶ added in v1.0.5
func (f *StructField) Indirect() reflect.Value
Indirect returns the value that StructField f.value points to. If f.value is a nil pointer, Indirect returns a zero Value. If f.value is not a pointer, Indirect returns f.value.
Example ¶
package main import ( "fmt" "github.com/roninzo/pointers" "github.com/roninzo/structs" ) func main() { type Server struct { Name *string `json:"name"` ID *uint `json:"id"` Enabled *bool `json:"enabled"` Count *int32 `json:"count"` } server := Server{ Name: pointers.String("Roninzo"), ID: pointers.Uint(uint(123456)), Enabled: pointers.Bool(true), Count: pointers.Int32(int32(5)), } s, err := structs.New(&server) if err != nil { fmt.Printf("Error : %v\n", err) } fmt.Printf("Name : %v\n", s.Name()) fmt.Printf("Value of ID : %v\n", s.Field("ID").Indirect()) fmt.Printf("Value of 0 : %v\n", s.Field(0).Indirect()) fmt.Printf("Value of Count : %v\n", s.Field("Count").Indirect()) fmt.Printf("Sprint: %s.\n", s.Sprint()) err = s.Field("ID").Set(pointers.Uint(uint(654321))) if err != nil { fmt.Printf("Error : %v\n", err) } err = s.Field("Count").Set(pointers.Int32(int32(6))) if err != nil { fmt.Printf("Error : %v\n", err) } err = s.Field("Enabled").Set(pointers.Int32(int32(6))) // not compatible with bool if err != nil { fmt.Printf("Error : %v\n", err) } fmt.Printf("Value of Name : %v\n", s.Field("Name").Indirect()) fmt.Printf("Value of ID : %v\n", s.Field("ID").Indirect()) fmt.Printf("Value of Count : %v\n", s.Field("Count").Indirect()) fmt.Printf("Sprint: %s.\n", s.Sprint()) fmt.Printf("\nVerification :\n") fmt.Printf("server.Name : %s\n", *server.Name) fmt.Printf("server.ID : %d\n", *server.ID) fmt.Printf("server.Count : %d\n", *server.Count) }
Output: Name : Server Value of ID : 123456 Value of 0 : Roninzo Value of Count : 5 Sprint: { "name": "Roninzo", "id": 123456, "enabled": true, "count": 5 }. Error : wrong kind of value for field Server.Enabled. got: "*int32" want: "*bool" Value of Name : Roninzo Value of ID : 654321 Value of Count : 6 Sprint: { "name": "Roninzo", "id": 654321, "enabled": true, "count": 6 }. Verification : server.Name : Roninzo server.ID : 654321 server.Count : 6
func (*StructField) IndirectType ¶ added in v1.0.5
func (f *StructField) IndirectType() reflect.Type
IndirectType returns the type that field f points to. If f is a pointer, IndirectType returns the type f points to. If f is not a pointer, IndirectType returns the type of f.
func (*StructField) Int ¶
func (f *StructField) Int() int64
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID int `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("ID") if f1.CanInt() { fmt.Printf("Int: %v\n", f1.Int()) } if f2.CanInt() { fmt.Printf("Int: %v\n", f2.Int()) } }
Output: Int: 123456
func (*StructField) Interface ¶
func (f *StructField) Interface() interface{}
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Anything interface{} `json:"anything,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Anything: 654321, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Anything") if f1.CanInterface() { fmt.Printf("Interface: %v.\n", f1.Interface()) } if f2.CanInterface() { fmt.Printf("Interface: %v.\n", f2.Interface()) } }
Output: Interface: 654321.
func (*StructField) IsAnonymous ¶
func (f *StructField) IsAnonymous() bool
IsAnonymous returns true if the given field is an anonymous field, meaning a field having no name. This obviously related to the use of the Name method.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type T3 struct { Config string `json:"config,omitempty"` } type T2 struct { Options string `json:"options,omitempty"` T3 } type T1 struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` Nested T2 `json:"t2,omitempty"` } t := T1{ "Roninzo", 123456, true, 0, "abcdefg", T2{"654321", T3{"cfg"}}, } s, err := structs.New(&t) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Password") f3 := s.Field("Nested").Struct().Field(0) fmt.Printf("IsAnonymous: %v\n", f1.IsAnonymous()) fmt.Printf("IsAnonymous: %v\n", f2.IsAnonymous()) fmt.Printf("IsAnonymous: %v\n", f3.IsAnonymous()) }
Output: IsAnonymous: false IsAnonymous: false IsAnonymous: false
func (*StructField) IsEmbedded ¶
func (f *StructField) IsEmbedded() bool
IsEmbedded is a alias to the IsAnonymous method. An embedded field can be an anonymous nested struct field.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type T3 struct { Config string `json:"config,omitempty"` } type T2 struct { Options string `json:"options,omitempty"` T3 } type T1 struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` Nested T2 `json:"t2,omitempty"` } t := T1{ "Roninzo", 123456, true, 0, "abcdefg", T2{"654321", T3{"cfg"}}, } s, err := structs.New(&t) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Password") f3 := s.Field("Nested").Struct().Field(0) fmt.Printf("IsEmbedded: %v\n", f1.IsEmbedded()) fmt.Printf("IsEmbedded: %v\n", f2.IsEmbedded()) fmt.Printf("IsEmbedded: %v\n", f3.IsEmbedded()) }
Output: IsEmbedded: false IsEmbedded: false IsEmbedded: false
func (*StructField) IsExported ¶
func (f *StructField) IsExported() bool
IsExported returns true if the given field is exported and its json tag is not equal to "-". Those fields are neglected for getter and setter methods.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } fmt.Printf("IsExported: %v\n", s.Field(0).IsExported()) fmt.Printf("IsExported: %v\n", s.Field("Password").IsExported()) fmt.Printf("IsExported: %v\n", s.Field("unexported").IsExported()) }
Output: IsExported: true IsExported: true IsExported: false
func (*StructField) IsHidden ¶
func (f *StructField) IsHidden() bool
IsHidden returns true if the given field is exported and its json tag is not equal to "-". Those fields are neglected for getter and setter methods.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } fmt.Printf("IsHidden: %v\n", s.Field(0).IsHidden()) fmt.Printf("IsHidden: %v\n", s.Field("Password").IsHidden()) fmt.Printf("IsHidden: %v\n", s.Field("unexported").IsHidden()) }
Output: IsHidden: false IsHidden: true IsHidden: false
func (*StructField) IsNil ¶
func (f *StructField) IsNil() bool
IsNil reports whether its argument f is nil. The argument must be a chan, func, interface, map, pointer, or slice value; if it is not, IsNil returns nil. Unexported struct fields will be neglected.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID *uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count *int32 `json:"count,omitempty"` Password *string `json:"-"` unexported bool } var id uint = 5 server := Server{ Name: "Roninzo", ID: &id, Enabled: true, Count: nil, Password: nil, unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("ID") f3 := s.Field("Count") f4 := s.Field("Password") fmt.Printf("IsNil: %v\n", f1.IsNil()) fmt.Printf("IsNil: %v\n", f2.IsNil()) fmt.Printf("IsNil: %v\n", f3.IsNil()) fmt.Printf("IsNil: %v\n", f4.IsNil()) }
Output: IsNil: false IsNil: false IsNil: true IsNil: true
func (*StructField) IsValid ¶
func (f *StructField) IsValid() bool
IsValid returns true if StructField has been loaded successfully. Useful for checking StructField is valid before use.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := &structs.StructField{} fmt.Printf("IsValid: %v\n", f1.IsValid()) fmt.Printf("IsValid: %v\n", f2.IsValid()) }
Output: IsValid: true IsValid: false
func (*StructField) IsZero ¶
func (f *StructField) IsZero() bool
IsZero returns true if the given field is a zero-value, i.e. not initialized. Unexported struct fields will be neglected.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Count") fmt.Printf("IsZero: %v\n", f1.IsZero()) fmt.Printf("IsZero: %v\n", f2.IsZero()) }
Output: IsZero: false IsZero: true
func (*StructField) Kind ¶
func (f *StructField) Kind() reflect.Kind
Kind returns the fields kind, such as "string", "int", "bool", etc ..
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Enabled") fmt.Printf("Kind: %v\n", f1.Kind()) fmt.Printf("Kind: %v\n", f2.Kind()) }
Output: Kind: string Kind: bool
func (*StructField) Name ¶
func (f *StructField) Name() string
Name returns returns the name of StructField, unless it was invalid. In which case, Name returns zero-value string.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Enabled") fmt.Printf("Field: %v\n", f1.Name()) fmt.Printf("Field: %v\n", f2.Name()) }
Output: Field: Name Field: Enabled
func (*StructField) NameJson ¶ added in v1.0.5
func (f *StructField) NameJson() string
NameJson returns returns the string name of StructField defined in its related json struct tag, else it generates it.
func (*StructField) Set ¶
func (f *StructField) Set(dest interface{}) error
Set sets the field to a given value dest. It returns an error if the field is not settable (not addressable or not exported) or if the given value's type doesn't match the fields type.
The are not expected for field ...
It has already been established that x is not nil by bailing out on the 'dest == nil' condition above.
- date <- date date <- text
- duration <- duration duration <- text duration <- number
- error <- error error <- text
- text <- text text <- bool text <- number text <- []byte text <- date
- bool <- bool bool <- text bool <- number
- number <- number number <- bool number <- float (losing decimal point value)
- float <- float float <- number
- []byte <- []byte []byte <- text
- complex <- complex
NOTE: Set might benefit from using reflect.Type.AssignableTo() or ConvertibleTo().
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Count") f3 := s.Field("unexported") fmt.Printf("Value: %v.\n", f1.Value()) fmt.Printf("Value: %v.\n", f2.Value()) fmt.Printf("Value: %v.\n", f3.Value()) err1 := f1.Set("Unknown") err2 := f2.Set(10) err3 := f3.Set(false) fmt.Printf("Value: %v.\n", f1.Value()) fmt.Printf("Value: %v.\n", f2.Value()) fmt.Printf("Value: %v.\n", f3.Value()) fmt.Printf("Error: %v.\n", err1) fmt.Printf("Error: %v.\n", err2) fmt.Printf("Error: %v.\n", err3) }
Output: Value: Roninzo. Value: 0. Value: false. Value: Unknown. Value: 10. Value: false. Error: <nil>. Error: <nil>. Error: could not set field Server.unexported: struct field is not settable.
Example (ValueToNil) ¶
package main import ( "fmt" "time" "github.com/pkg/errors" "github.com/roninzo/pointers" "github.com/roninzo/structs" ) type structTest struct { String string `json:"string,omitempty"` Bool bool `json:"bool,omitempty"` Int int `json:"int,omitempty"` Uint uint `json:"uint,omitempty"` Float float32 `json:"float,omitempty"` Complex complex128 `json:"complex,omitempty"` Bytes []byte `json:"bytes,omitempty"` Interface interface{} `json:"interface,omitempty"` Error error `json:"error,omitempty"` Time time.Time `json:"time,omitempty"` Duration time.Duration `json:"duration,omitempty"` NestedStruct structNested `json:"nested_struct,omitempty"` PtrString *string `json:"pointer_string,omitempty"` PtrBool *bool `json:"pointer_bool,omitempty"` PtrInt *int `json:"pointer_int,omitempty"` PtrUint *uint `json:"pointer_uint,omitempty"` PtrFloat *float32 `json:"pointer_float,omitempty"` PtrComplex *complex128 `json:"pointer_complex,omitempty"` PtrError *error `json:"pointer_error,omitempty"` PtrTime *time.Time `json:"pointer_time,omitempty"` PtrDuration *time.Duration `json:"pointer_duration,omitempty"` PtrNestedStruct *structNested `json:"pointer_nested_struct,omitempty"` MapString map[string]string `json:"map_string,omitempty"` MapBool map[string]bool `json:"map_bool,omitempty"` MapInt map[string]int `json:"mapint,omitempty"` MapUint map[string]uint `json:"map_uint,omitempty"` MapFloat map[string]float32 `json:"map_float,omitempty"` MapComplex map[string]complex128 `json:"map_complex,omitempty"` MapInterface map[string]interface{} `json:"map_interface,omitempty"` SliceString []string `json:"slice_string,omitempty"` SliceBool []bool `json:"slice_bool,omitempty"` SliceInt []int `json:"slice_int,omitempty"` SliceUint []uint `json:"slice_uint,omitempty"` SliceFloat []float32 `json:"slice_float,omitempty"` SliceComplex []complex128 `json:"slice_complex,omitempty"` SliceInterface []interface{} `json:"slice_interface,omitempty"` SlicePtrString []*string `json:"slice_pointer_string,omitempty"` SlicePtrBool []*bool `json:"slice_pointer_bool,omitempty"` SlicePtrInt []*int `json:"slice_pointer_int,omitempty"` SlicePtrUint []*uint `json:"slice_pointer_uint,omitempty"` SlicePtrFloat []*float32 `json:"slice_pointer_float,omitempty"` SlicePtrComplex []*complex128 `json:"slice_pointer_complex,omitempty"` Hidden string `json:"-"` unexported bool } type structNested struct { Uint uint `json:"uint,omitempty"` String string `json:"string,omitempty"` } var structFieldNames []string = []string{ "String", "PtrString", "MapString", "SliceString", "SlicePtrString", "Bool", "PtrBool", "MapBool", "SliceBool", "SlicePtrBool", "Int", "PtrInt", "MapInt", "SliceInt", "SlicePtrInt", "Uint", "PtrUint", "MapUint", "SliceUint", "SlicePtrUint", "Float", "PtrFloat", "MapFloat", "SliceFloat", "SlicePtrFloat", "Complex", "PtrComplex", "MapComplex", "SliceComplex", "SlicePtrComplex", "Interface", "MapInterface", "SliceInterface", "Bytes", "Error", "PtrError", "Time", "PtrTime", "Duration", "PtrDuration", "NestedStruct", "PtrNestedStruct", "Hidden", "unexported", } var structX structTest = structTest{ String: "ozninoR", Bool: false, Int: 3, Uint: uint(654321), Float: 7622.50, Complex: complex(-67, -42), Bytes: []byte("Bye bye world"), Interface: 3.99, Error: errors.New("not compliant"), Time: time.Date(2021, time.August, 31, 14, 11, 11, 0, time.UTC), Duration: 30 * time.Second, NestedStruct: structNested{Uint: 443211, String: "Microsoft IIS"}, PtrString: pointers.String("ozninoR"), PtrBool: pointers.Bool(false), PtrInt: pointers.Int(3), PtrUint: pointers.Uint(uint(654321)), PtrFloat: pointers.Float32(7622.50), PtrComplex: pointers.Complex128(complex(-67, -42)), PtrError: pointers.Error(errors.New("not compliant")), PtrTime: pointers.Time(time.Date(2021, time.August, 31, 14, 11, 11, 0, time.UTC)), PtrDuration: pointers.Duration(30 * time.Second), PtrNestedStruct: &structNested{Uint: 443211, String: "Microsoft IIS"}, MapString: map[string]string{"D": "four", "E": "five", "F": "six"}, MapBool: map[string]bool{"D": false, "E": true}, MapInt: map[string]int{"D": 4, "E": 5, "F": 6}, MapUint: map[string]uint{"D": uint(4), "E": uint(5), "F": uint(6)}, MapFloat: map[string]float32{"D": 1.4, "E": 1.5, "F": 1.6}, MapComplex: map[string]complex128{"D": complex(1, 4), "E": complex(1, 5), "F": complex(1, 6)}, MapInterface: map[string]interface{}{"D": 4, "E": "five", "F": 6.0}, SliceString: []string{"four", "five", "six"}, SliceBool: []bool{false, true}, SliceInt: []int{4, 5, 6}, SliceUint: []uint{uint(4), uint(5), uint(6)}, SliceFloat: []float32{1.4, 1.5, 1.6}, SliceComplex: []complex128{complex(1, 4), complex(1, 5), complex(1, 6)}, SliceInterface: []interface{}{4, "five", 6.0}, SlicePtrString: []*string{pointers.String("four"), pointers.String("five"), pointers.String("six")}, SlicePtrBool: []*bool{pointers.Bool(false), pointers.Bool(true)}, SlicePtrInt: []*int{pointers.Int(4), pointers.Int(5), pointers.Int(6)}, SlicePtrUint: []*uint{pointers.Uint(uint(4)), pointers.Uint(uint(5)), pointers.Uint(uint(6))}, SlicePtrFloat: []*float32{pointers.Float32(1.4), pointers.Float32(1.5), pointers.Float32(1.6)}, SlicePtrComplex: []*complex128{pointers.Complex128(complex(1, 4)), pointers.Complex128(complex(1, 5)), pointers.Complex128(complex(1, 6))}, Hidden: "gfedcba", unexported: false, } func printStruct(s *structTest) { format := "- %15s: %v.\n" formatStruct := "- %15s: %+v.\n" formatPointer := "- %15s: *%v.\n" formatPtrStruct := "- %15s: *%+v.\n" fmt.Printf(format, "String", s.String) fmt.Printf(format, "Bool", s.Bool) fmt.Printf(format, "Int", s.Int) fmt.Printf(format, "Uint", s.Uint) fmt.Printf(format, "Float", s.Float) fmt.Printf(format, "Complex", s.Complex) fmt.Printf(format, "Bytes", string(s.Bytes)) fmt.Printf(format, "Interface", s.Interface) fmt.Printf(format, "Error", s.Error) fmt.Printf(format, "Time", s.Time) fmt.Printf(format, "Duration", s.Duration) fmt.Printf(formatStruct, "NestedStruct", s.NestedStruct) if s.PtrString != nil { fmt.Printf(formatPointer, "PtrString", *s.PtrString) } else { fmt.Printf(format, "PtrString", s.PtrString) } if s.PtrBool != nil { fmt.Printf(formatPointer, "PtrBool", *s.PtrBool) } else { fmt.Printf(format, "PtrBool", s.PtrBool) } if s.PtrInt != nil { fmt.Printf(formatPointer, "PtrInt", *s.PtrInt) } else { fmt.Printf(format, "PtrInt", s.PtrInt) } if s.PtrUint != nil { fmt.Printf(formatPointer, "PtrUint", *s.PtrUint) } else { fmt.Printf(format, "PtrUint", s.PtrUint) } if s.PtrFloat != nil { fmt.Printf(formatPointer, "PtrFloat", *s.PtrFloat) } else { fmt.Printf(format, "PtrFloat", s.PtrFloat) } if s.PtrComplex != nil { fmt.Printf(formatPointer, "PtrComplex", *s.PtrComplex) } else { fmt.Printf(format, "PtrComplex", s.PtrComplex) } if s.PtrError != nil { fmt.Printf(formatPointer, "PtrError", *s.PtrError) } else { fmt.Printf(format, "PtrError", s.PtrError) } if s.PtrTime != nil { fmt.Printf(formatPointer, "PtrTime", *s.PtrTime) } else { fmt.Printf(format, "PtrTime", s.PtrTime) } if s.PtrDuration != nil { fmt.Printf(formatPointer, "PtrDuration", *s.PtrDuration) } else { fmt.Printf(format, "PtrDuration", s.PtrDuration) } if s.PtrNestedStruct != nil { fmt.Printf(formatPtrStruct, "PtrNestedStruct", *s.PtrNestedStruct) } else { fmt.Printf(formatStruct, "PtrNestedStruct", s.PtrNestedStruct) } fmt.Printf(format, "MapString", s.MapString) fmt.Printf(format, "MapBool", s.MapBool) fmt.Printf(format, "MapInt", s.MapInt) fmt.Printf(format, "MapUint", s.MapUint) fmt.Printf(format, "MapFloat", s.MapFloat) fmt.Printf(format, "MapComplex", s.MapComplex) fmt.Printf(format, "MapInterface", s.MapInterface) fmt.Printf(format, "SliceString", s.SliceString) fmt.Printf(format, "SliceBool", s.SliceBool) fmt.Printf(format, "SliceInt", s.SliceInt) fmt.Printf(format, "SliceUint", s.SliceUint) fmt.Printf(format, "SliceFloat", s.SliceFloat) fmt.Printf(format, "SliceComplex", s.SliceComplex) fmt.Printf(format, "SliceInterface", s.SliceInterface) { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrString { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrString", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrBool { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrBool", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrInt { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrInt", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrUint { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrUint", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrFloat { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrFloat", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrComplex { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrComplex", m) } fmt.Printf(format, "Hidden", s.Hidden) fmt.Printf(format, "unexported", s.unexported) } func main() { t := structX s, err := structs.New(&t) if err != nil { fmt.Printf("New[Error]: %v.\n", err) return } for _, name := range structFieldNames { err := s.Field(name).SetNil() if err != nil { fmt.Printf("SetNil[Error]: %v.\n", err) } } printStruct(&t) }
Output: SetNil[Error]: could not set field structTest.String to nil: struct field is not nillable. SetNil[Error]: could not set field structTest.Bool to nil: struct field is not nillable. SetNil[Error]: could not set field structTest.Int to nil: struct field is not nillable. SetNil[Error]: could not set field structTest.Uint to nil: struct field is not nillable. SetNil[Error]: could not set field structTest.Float to nil: struct field is not nillable. SetNil[Error]: could not set field structTest.Complex to nil: struct field is not nillable. SetNil[Error]: could not set field structTest.Time to nil: struct field is not nillable. SetNil[Error]: could not set field structTest.Duration to nil: struct field is not nillable. SetNil[Error]: could not set field structTest.NestedStruct to nil: struct field is not nillable. SetNil[Error]: could not set field structTest.Hidden to nil: struct field is not nillable. SetNil[Error]: could not set field structTest.unexported to nil: struct field is not settable. - String: ozninoR. - Bool: false. - Int: 3. - Uint: 654321. - Float: 7622.5. - Complex: (-67-42i). - Bytes: . - Interface: <nil>. - Error: <nil>. - Time: 2021-08-31 14:11:11 +0000 UTC. - Duration: 30s. - NestedStruct: {Uint:443211 String:Microsoft IIS}. - PtrString: <nil>. - PtrBool: <nil>. - PtrInt: <nil>. - PtrUint: <nil>. - PtrFloat: <nil>. - PtrComplex: <nil>. - PtrError: <nil>. - PtrTime: <nil>. - PtrDuration: <nil>. - PtrNestedStruct: <nil>. - MapString: map[]. - MapBool: map[]. - MapInt: map[]. - MapUint: map[]. - MapFloat: map[]. - MapComplex: map[]. - MapInterface: map[]. - SliceString: []. - SliceBool: []. - SliceInt: []. - SliceUint: []. - SliceFloat: []. - SliceComplex: []. - SliceInterface: []. - SlicePtrString: []. - SlicePtrBool: []. - SlicePtrInt: []. - SlicePtrUint: []. - SlicePtrFloat: []. - SlicePtrComplex: []. - Hidden: gfedcba. - unexported: false.
Example (ValueToValue) ¶
package main import ( "fmt" "time" "github.com/pkg/errors" "github.com/roninzo/pointers" "github.com/roninzo/structs" ) type structTest struct { String string `json:"string,omitempty"` Bool bool `json:"bool,omitempty"` Int int `json:"int,omitempty"` Uint uint `json:"uint,omitempty"` Float float32 `json:"float,omitempty"` Complex complex128 `json:"complex,omitempty"` Bytes []byte `json:"bytes,omitempty"` Interface interface{} `json:"interface,omitempty"` Error error `json:"error,omitempty"` Time time.Time `json:"time,omitempty"` Duration time.Duration `json:"duration,omitempty"` NestedStruct structNested `json:"nested_struct,omitempty"` PtrString *string `json:"pointer_string,omitempty"` PtrBool *bool `json:"pointer_bool,omitempty"` PtrInt *int `json:"pointer_int,omitempty"` PtrUint *uint `json:"pointer_uint,omitempty"` PtrFloat *float32 `json:"pointer_float,omitempty"` PtrComplex *complex128 `json:"pointer_complex,omitempty"` PtrError *error `json:"pointer_error,omitempty"` PtrTime *time.Time `json:"pointer_time,omitempty"` PtrDuration *time.Duration `json:"pointer_duration,omitempty"` PtrNestedStruct *structNested `json:"pointer_nested_struct,omitempty"` MapString map[string]string `json:"map_string,omitempty"` MapBool map[string]bool `json:"map_bool,omitempty"` MapInt map[string]int `json:"mapint,omitempty"` MapUint map[string]uint `json:"map_uint,omitempty"` MapFloat map[string]float32 `json:"map_float,omitempty"` MapComplex map[string]complex128 `json:"map_complex,omitempty"` MapInterface map[string]interface{} `json:"map_interface,omitempty"` SliceString []string `json:"slice_string,omitempty"` SliceBool []bool `json:"slice_bool,omitempty"` SliceInt []int `json:"slice_int,omitempty"` SliceUint []uint `json:"slice_uint,omitempty"` SliceFloat []float32 `json:"slice_float,omitempty"` SliceComplex []complex128 `json:"slice_complex,omitempty"` SliceInterface []interface{} `json:"slice_interface,omitempty"` SlicePtrString []*string `json:"slice_pointer_string,omitempty"` SlicePtrBool []*bool `json:"slice_pointer_bool,omitempty"` SlicePtrInt []*int `json:"slice_pointer_int,omitempty"` SlicePtrUint []*uint `json:"slice_pointer_uint,omitempty"` SlicePtrFloat []*float32 `json:"slice_pointer_float,omitempty"` SlicePtrComplex []*complex128 `json:"slice_pointer_complex,omitempty"` Hidden string `json:"-"` unexported bool } type structNested struct { Uint uint `json:"uint,omitempty"` String string `json:"string,omitempty"` } var structV structTest = structTest{ String: "Roninzo", Bool: true, Int: 8, Uint: uint(123456), Float: 1922.50, Complex: complex(22, 50), Bytes: []byte("Hello world"), Interface: "anything", Error: errors.New("rows not found"), Time: time.Date(2021, time.August, 3, 16, 44, 46, 0, time.UTC), Duration: 5 * time.Second, NestedStruct: structNested{Uint: 122334, String: "Apache"}, PtrString: pointers.String("Roninzo"), PtrBool: pointers.Bool(true), PtrInt: pointers.Int(8), PtrUint: pointers.Uint(uint(123456)), PtrFloat: pointers.Float32(1922.50), PtrComplex: pointers.Complex128(complex(22, 50)), PtrError: pointers.Error(errors.New("rows not found")), PtrTime: pointers.Time(time.Date(2021, time.August, 3, 16, 44, 46, 0, time.UTC)), PtrDuration: pointers.Duration(5 * time.Second), PtrNestedStruct: &structNested{Uint: 122334, String: "Apache"}, MapString: map[string]string{"A": "one", "B": "two", "C": "three"}, MapBool: map[string]bool{"A": true, "B": false}, MapInt: map[string]int{"A": 1, "B": 2, "C": 3}, MapUint: map[string]uint{"A": uint(1), "B": uint(2), "C": uint(3)}, MapFloat: map[string]float32{"A": 1.1, "B": 1.2, "C": 1.3}, MapComplex: map[string]complex128{"A": complex(1, 1), "B": complex(1, 2), "C": complex(1, 3)}, MapInterface: map[string]interface{}{"A": 1, "B": "two", "C": 3.0}, SliceString: []string{"one", "two", "three"}, SliceBool: []bool{true, false}, SliceInt: []int{1, 2, 3}, SliceUint: []uint{uint(1), uint(2), uint(3)}, SliceFloat: []float32{1.1, 1.2, 1.3}, SliceComplex: []complex128{complex(1, 1), complex(1, 2), complex(1, 3)}, SliceInterface: []interface{}{1, "two", 3.0}, SlicePtrString: []*string{pointers.String("one"), pointers.String("two"), pointers.String("three")}, SlicePtrBool: []*bool{pointers.Bool(true), pointers.Bool(false)}, SlicePtrInt: []*int{pointers.Int(1), pointers.Int(2), pointers.Int(3)}, SlicePtrUint: []*uint{pointers.Uint(uint(1)), pointers.Uint(uint(2)), pointers.Uint(uint(3))}, SlicePtrFloat: []*float32{pointers.Float32(1.1), pointers.Float32(1.2), pointers.Float32(1.3)}, SlicePtrComplex: []*complex128{pointers.Complex128(complex(1, 1)), pointers.Complex128(complex(1, 2)), pointers.Complex128(complex(1, 3))}, Hidden: "abcdefg", unexported: true, } var structX structTest = structTest{ String: "ozninoR", Bool: false, Int: 3, Uint: uint(654321), Float: 7622.50, Complex: complex(-67, -42), Bytes: []byte("Bye bye world"), Interface: 3.99, Error: errors.New("not compliant"), Time: time.Date(2021, time.August, 31, 14, 11, 11, 0, time.UTC), Duration: 30 * time.Second, NestedStruct: structNested{Uint: 443211, String: "Microsoft IIS"}, PtrString: pointers.String("ozninoR"), PtrBool: pointers.Bool(false), PtrInt: pointers.Int(3), PtrUint: pointers.Uint(uint(654321)), PtrFloat: pointers.Float32(7622.50), PtrComplex: pointers.Complex128(complex(-67, -42)), PtrError: pointers.Error(errors.New("not compliant")), PtrTime: pointers.Time(time.Date(2021, time.August, 31, 14, 11, 11, 0, time.UTC)), PtrDuration: pointers.Duration(30 * time.Second), PtrNestedStruct: &structNested{Uint: 443211, String: "Microsoft IIS"}, MapString: map[string]string{"D": "four", "E": "five", "F": "six"}, MapBool: map[string]bool{"D": false, "E": true}, MapInt: map[string]int{"D": 4, "E": 5, "F": 6}, MapUint: map[string]uint{"D": uint(4), "E": uint(5), "F": uint(6)}, MapFloat: map[string]float32{"D": 1.4, "E": 1.5, "F": 1.6}, MapComplex: map[string]complex128{"D": complex(1, 4), "E": complex(1, 5), "F": complex(1, 6)}, MapInterface: map[string]interface{}{"D": 4, "E": "five", "F": 6.0}, SliceString: []string{"four", "five", "six"}, SliceBool: []bool{false, true}, SliceInt: []int{4, 5, 6}, SliceUint: []uint{uint(4), uint(5), uint(6)}, SliceFloat: []float32{1.4, 1.5, 1.6}, SliceComplex: []complex128{complex(1, 4), complex(1, 5), complex(1, 6)}, SliceInterface: []interface{}{4, "five", 6.0}, SlicePtrString: []*string{pointers.String("four"), pointers.String("five"), pointers.String("six")}, SlicePtrBool: []*bool{pointers.Bool(false), pointers.Bool(true)}, SlicePtrInt: []*int{pointers.Int(4), pointers.Int(5), pointers.Int(6)}, SlicePtrUint: []*uint{pointers.Uint(uint(4)), pointers.Uint(uint(5)), pointers.Uint(uint(6))}, SlicePtrFloat: []*float32{pointers.Float32(1.4), pointers.Float32(1.5), pointers.Float32(1.6)}, SlicePtrComplex: []*complex128{pointers.Complex128(complex(1, 4)), pointers.Complex128(complex(1, 5)), pointers.Complex128(complex(1, 6))}, Hidden: "gfedcba", unexported: false, } func printStruct(s *structTest) { format := "- %15s: %v.\n" formatStruct := "- %15s: %+v.\n" formatPointer := "- %15s: *%v.\n" formatPtrStruct := "- %15s: *%+v.\n" fmt.Printf(format, "String", s.String) fmt.Printf(format, "Bool", s.Bool) fmt.Printf(format, "Int", s.Int) fmt.Printf(format, "Uint", s.Uint) fmt.Printf(format, "Float", s.Float) fmt.Printf(format, "Complex", s.Complex) fmt.Printf(format, "Bytes", string(s.Bytes)) fmt.Printf(format, "Interface", s.Interface) fmt.Printf(format, "Error", s.Error) fmt.Printf(format, "Time", s.Time) fmt.Printf(format, "Duration", s.Duration) fmt.Printf(formatStruct, "NestedStruct", s.NestedStruct) if s.PtrString != nil { fmt.Printf(formatPointer, "PtrString", *s.PtrString) } else { fmt.Printf(format, "PtrString", s.PtrString) } if s.PtrBool != nil { fmt.Printf(formatPointer, "PtrBool", *s.PtrBool) } else { fmt.Printf(format, "PtrBool", s.PtrBool) } if s.PtrInt != nil { fmt.Printf(formatPointer, "PtrInt", *s.PtrInt) } else { fmt.Printf(format, "PtrInt", s.PtrInt) } if s.PtrUint != nil { fmt.Printf(formatPointer, "PtrUint", *s.PtrUint) } else { fmt.Printf(format, "PtrUint", s.PtrUint) } if s.PtrFloat != nil { fmt.Printf(formatPointer, "PtrFloat", *s.PtrFloat) } else { fmt.Printf(format, "PtrFloat", s.PtrFloat) } if s.PtrComplex != nil { fmt.Printf(formatPointer, "PtrComplex", *s.PtrComplex) } else { fmt.Printf(format, "PtrComplex", s.PtrComplex) } if s.PtrError != nil { fmt.Printf(formatPointer, "PtrError", *s.PtrError) } else { fmt.Printf(format, "PtrError", s.PtrError) } if s.PtrTime != nil { fmt.Printf(formatPointer, "PtrTime", *s.PtrTime) } else { fmt.Printf(format, "PtrTime", s.PtrTime) } if s.PtrDuration != nil { fmt.Printf(formatPointer, "PtrDuration", *s.PtrDuration) } else { fmt.Printf(format, "PtrDuration", s.PtrDuration) } if s.PtrNestedStruct != nil { fmt.Printf(formatPtrStruct, "PtrNestedStruct", *s.PtrNestedStruct) } else { fmt.Printf(formatStruct, "PtrNestedStruct", s.PtrNestedStruct) } fmt.Printf(format, "MapString", s.MapString) fmt.Printf(format, "MapBool", s.MapBool) fmt.Printf(format, "MapInt", s.MapInt) fmt.Printf(format, "MapUint", s.MapUint) fmt.Printf(format, "MapFloat", s.MapFloat) fmt.Printf(format, "MapComplex", s.MapComplex) fmt.Printf(format, "MapInterface", s.MapInterface) fmt.Printf(format, "SliceString", s.SliceString) fmt.Printf(format, "SliceBool", s.SliceBool) fmt.Printf(format, "SliceInt", s.SliceInt) fmt.Printf(format, "SliceUint", s.SliceUint) fmt.Printf(format, "SliceFloat", s.SliceFloat) fmt.Printf(format, "SliceComplex", s.SliceComplex) fmt.Printf(format, "SliceInterface", s.SliceInterface) { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrString { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrString", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrBool { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrBool", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrInt { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrInt", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrUint { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrUint", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrFloat { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrFloat", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrComplex { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrComplex", m) } fmt.Printf(format, "Hidden", s.Hidden) fmt.Printf(format, "unexported", s.unexported) } func main() { t := structV s, err := structs.New(&t) if err != nil { fmt.Printf("New[Error]: %v.\n", err) return } err = s.Field("String").Set(structX.String) err = s.Field("Bool").Set(structX.Bool) err = s.Field("Int").Set(structX.Int) err = s.Field("Uint").Set(structX.Uint) err = s.Field("Float").Set(structX.Float) err = s.Field("Complex").Set(structX.Complex) err = s.Field("Bytes").Set(structX.Bytes) err = s.Field("Interface").Set(structX.Interface) err = s.Field("Error").Set(structX.Error) err = s.Field("Time").Set(structX.Time) err = s.Field("Duration").Set(structX.Duration) err = s.Field("NestedStruct").Set(structX.NestedStruct) err = s.Field("PtrString").Set(structX.PtrString) err = s.Field("PtrBool").Set(structX.PtrBool) err = s.Field("PtrInt").Set(structX.PtrInt) err = s.Field("PtrUint").Set(structX.PtrUint) err = s.Field("PtrFloat").Set(structX.PtrFloat) err = s.Field("PtrComplex").Set(structX.PtrComplex) err = s.Field("PtrError").Set(structX.PtrError) err = s.Field("PtrTime").Set(structX.PtrTime) err = s.Field("PtrDuration").Set(structX.PtrDuration) err = s.Field("PtrNestedStruct").Set(structX.PtrNestedStruct) err = s.Field("MapString").Set(structX.MapString) err = s.Field("MapBool").Set(structX.MapBool) err = s.Field("MapInt").Set(structX.MapInt) err = s.Field("MapUint").Set(structX.MapUint) err = s.Field("MapFloat").Set(structX.MapFloat) err = s.Field("MapComplex").Set(structX.MapComplex) err = s.Field("MapInterface").Set(structX.MapInterface) err = s.Field("SliceString").Set(structX.SliceString) err = s.Field("SliceBool").Set(structX.SliceBool) err = s.Field("SliceInt").Set(structX.SliceInt) err = s.Field("SliceUint").Set(structX.SliceUint) err = s.Field("SliceFloat").Set(structX.SliceFloat) err = s.Field("SliceComplex").Set(structX.SliceComplex) err = s.Field("SliceInterface").Set(structX.SliceInterface) err = s.Field("SlicePtrString").Set(structX.SlicePtrString) err = s.Field("SlicePtrBool").Set(structX.SlicePtrBool) err = s.Field("SlicePtrInt").Set(structX.SlicePtrInt) err = s.Field("SlicePtrUint").Set(structX.SlicePtrUint) err = s.Field("SlicePtrFloat").Set(structX.SlicePtrFloat) err = s.Field("SlicePtrComplex").Set(structX.SlicePtrComplex) err = s.Field("Hidden").Set(structX.Hidden) err = s.Field("unexported").Set(structX.unexported) if err != nil { fmt.Printf("Set[Error]: %v.\n", err) } printStruct(&t) }
Output: Set[Error]: could not set field structTest.unexported: struct field is not settable. - String: ozninoR. - Bool: false. - Int: 3. - Uint: 654321. - Float: 7622.5. - Complex: (-67-42i). - Bytes: Bye bye world. - Interface: 3.99. - Error: not compliant. - Time: 2021-08-31 14:11:11 +0000 UTC. - Duration: 30s. - NestedStruct: {Uint:443211 String:Microsoft IIS}. - PtrString: *ozninoR. - PtrBool: *false. - PtrInt: *3. - PtrUint: *654321. - PtrFloat: *7622.5. - PtrComplex: *(-67-42i). - PtrError: *not compliant. - PtrTime: *2021-08-31 14:11:11 +0000 UTC. - PtrDuration: *30s. - PtrNestedStruct: *{Uint:443211 String:Microsoft IIS}. - MapString: map[D:four E:five F:six]. - MapBool: map[D:false E:true]. - MapInt: map[D:4 E:5 F:6]. - MapUint: map[D:4 E:5 F:6]. - MapFloat: map[D:1.4 E:1.5 F:1.6]. - MapComplex: map[D:(1+4i) E:(1+5i) F:(1+6i)]. - MapInterface: map[D:4 E:five F:6]. - SliceString: [four five six]. - SliceBool: [false true]. - SliceInt: [4 5 6]. - SliceUint: [4 5 6]. - SliceFloat: [1.4 1.5 1.6]. - SliceComplex: [(1+4i) (1+5i) (1+6i)]. - SliceInterface: [4 five 6]. - SlicePtrString: [*four *five *six]. - SlicePtrBool: [*false *true]. - SlicePtrInt: [*4 *5 *6]. - SlicePtrUint: [*4 *5 *6]. - SlicePtrFloat: [*1.4 *1.5 *1.6]. - SlicePtrComplex: [*(1+4i) *(1+5i) *(1+6i)]. - Hidden: gfedcba. - unexported: true.
Example (ValueToZero) ¶
package main import ( "fmt" "time" "github.com/pkg/errors" "github.com/roninzo/pointers" "github.com/roninzo/structs" ) type structTest struct { String string `json:"string,omitempty"` Bool bool `json:"bool,omitempty"` Int int `json:"int,omitempty"` Uint uint `json:"uint,omitempty"` Float float32 `json:"float,omitempty"` Complex complex128 `json:"complex,omitempty"` Bytes []byte `json:"bytes,omitempty"` Interface interface{} `json:"interface,omitempty"` Error error `json:"error,omitempty"` Time time.Time `json:"time,omitempty"` Duration time.Duration `json:"duration,omitempty"` NestedStruct structNested `json:"nested_struct,omitempty"` PtrString *string `json:"pointer_string,omitempty"` PtrBool *bool `json:"pointer_bool,omitempty"` PtrInt *int `json:"pointer_int,omitempty"` PtrUint *uint `json:"pointer_uint,omitempty"` PtrFloat *float32 `json:"pointer_float,omitempty"` PtrComplex *complex128 `json:"pointer_complex,omitempty"` PtrError *error `json:"pointer_error,omitempty"` PtrTime *time.Time `json:"pointer_time,omitempty"` PtrDuration *time.Duration `json:"pointer_duration,omitempty"` PtrNestedStruct *structNested `json:"pointer_nested_struct,omitempty"` MapString map[string]string `json:"map_string,omitempty"` MapBool map[string]bool `json:"map_bool,omitempty"` MapInt map[string]int `json:"mapint,omitempty"` MapUint map[string]uint `json:"map_uint,omitempty"` MapFloat map[string]float32 `json:"map_float,omitempty"` MapComplex map[string]complex128 `json:"map_complex,omitempty"` MapInterface map[string]interface{} `json:"map_interface,omitempty"` SliceString []string `json:"slice_string,omitempty"` SliceBool []bool `json:"slice_bool,omitempty"` SliceInt []int `json:"slice_int,omitempty"` SliceUint []uint `json:"slice_uint,omitempty"` SliceFloat []float32 `json:"slice_float,omitempty"` SliceComplex []complex128 `json:"slice_complex,omitempty"` SliceInterface []interface{} `json:"slice_interface,omitempty"` SlicePtrString []*string `json:"slice_pointer_string,omitempty"` SlicePtrBool []*bool `json:"slice_pointer_bool,omitempty"` SlicePtrInt []*int `json:"slice_pointer_int,omitempty"` SlicePtrUint []*uint `json:"slice_pointer_uint,omitempty"` SlicePtrFloat []*float32 `json:"slice_pointer_float,omitempty"` SlicePtrComplex []*complex128 `json:"slice_pointer_complex,omitempty"` Hidden string `json:"-"` unexported bool } type structNested struct { Uint uint `json:"uint,omitempty"` String string `json:"string,omitempty"` } var structFieldNames []string = []string{ "String", "PtrString", "MapString", "SliceString", "SlicePtrString", "Bool", "PtrBool", "MapBool", "SliceBool", "SlicePtrBool", "Int", "PtrInt", "MapInt", "SliceInt", "SlicePtrInt", "Uint", "PtrUint", "MapUint", "SliceUint", "SlicePtrUint", "Float", "PtrFloat", "MapFloat", "SliceFloat", "SlicePtrFloat", "Complex", "PtrComplex", "MapComplex", "SliceComplex", "SlicePtrComplex", "Interface", "MapInterface", "SliceInterface", "Bytes", "Error", "PtrError", "Time", "PtrTime", "Duration", "PtrDuration", "NestedStruct", "PtrNestedStruct", "Hidden", "unexported", } var structX structTest = structTest{ String: "ozninoR", Bool: false, Int: 3, Uint: uint(654321), Float: 7622.50, Complex: complex(-67, -42), Bytes: []byte("Bye bye world"), Interface: 3.99, Error: errors.New("not compliant"), Time: time.Date(2021, time.August, 31, 14, 11, 11, 0, time.UTC), Duration: 30 * time.Second, NestedStruct: structNested{Uint: 443211, String: "Microsoft IIS"}, PtrString: pointers.String("ozninoR"), PtrBool: pointers.Bool(false), PtrInt: pointers.Int(3), PtrUint: pointers.Uint(uint(654321)), PtrFloat: pointers.Float32(7622.50), PtrComplex: pointers.Complex128(complex(-67, -42)), PtrError: pointers.Error(errors.New("not compliant")), PtrTime: pointers.Time(time.Date(2021, time.August, 31, 14, 11, 11, 0, time.UTC)), PtrDuration: pointers.Duration(30 * time.Second), PtrNestedStruct: &structNested{Uint: 443211, String: "Microsoft IIS"}, MapString: map[string]string{"D": "four", "E": "five", "F": "six"}, MapBool: map[string]bool{"D": false, "E": true}, MapInt: map[string]int{"D": 4, "E": 5, "F": 6}, MapUint: map[string]uint{"D": uint(4), "E": uint(5), "F": uint(6)}, MapFloat: map[string]float32{"D": 1.4, "E": 1.5, "F": 1.6}, MapComplex: map[string]complex128{"D": complex(1, 4), "E": complex(1, 5), "F": complex(1, 6)}, MapInterface: map[string]interface{}{"D": 4, "E": "five", "F": 6.0}, SliceString: []string{"four", "five", "six"}, SliceBool: []bool{false, true}, SliceInt: []int{4, 5, 6}, SliceUint: []uint{uint(4), uint(5), uint(6)}, SliceFloat: []float32{1.4, 1.5, 1.6}, SliceComplex: []complex128{complex(1, 4), complex(1, 5), complex(1, 6)}, SliceInterface: []interface{}{4, "five", 6.0}, SlicePtrString: []*string{pointers.String("four"), pointers.String("five"), pointers.String("six")}, SlicePtrBool: []*bool{pointers.Bool(false), pointers.Bool(true)}, SlicePtrInt: []*int{pointers.Int(4), pointers.Int(5), pointers.Int(6)}, SlicePtrUint: []*uint{pointers.Uint(uint(4)), pointers.Uint(uint(5)), pointers.Uint(uint(6))}, SlicePtrFloat: []*float32{pointers.Float32(1.4), pointers.Float32(1.5), pointers.Float32(1.6)}, SlicePtrComplex: []*complex128{pointers.Complex128(complex(1, 4)), pointers.Complex128(complex(1, 5)), pointers.Complex128(complex(1, 6))}, Hidden: "gfedcba", unexported: false, } func printStruct(s *structTest) { format := "- %15s: %v.\n" formatStruct := "- %15s: %+v.\n" formatPointer := "- %15s: *%v.\n" formatPtrStruct := "- %15s: *%+v.\n" fmt.Printf(format, "String", s.String) fmt.Printf(format, "Bool", s.Bool) fmt.Printf(format, "Int", s.Int) fmt.Printf(format, "Uint", s.Uint) fmt.Printf(format, "Float", s.Float) fmt.Printf(format, "Complex", s.Complex) fmt.Printf(format, "Bytes", string(s.Bytes)) fmt.Printf(format, "Interface", s.Interface) fmt.Printf(format, "Error", s.Error) fmt.Printf(format, "Time", s.Time) fmt.Printf(format, "Duration", s.Duration) fmt.Printf(formatStruct, "NestedStruct", s.NestedStruct) if s.PtrString != nil { fmt.Printf(formatPointer, "PtrString", *s.PtrString) } else { fmt.Printf(format, "PtrString", s.PtrString) } if s.PtrBool != nil { fmt.Printf(formatPointer, "PtrBool", *s.PtrBool) } else { fmt.Printf(format, "PtrBool", s.PtrBool) } if s.PtrInt != nil { fmt.Printf(formatPointer, "PtrInt", *s.PtrInt) } else { fmt.Printf(format, "PtrInt", s.PtrInt) } if s.PtrUint != nil { fmt.Printf(formatPointer, "PtrUint", *s.PtrUint) } else { fmt.Printf(format, "PtrUint", s.PtrUint) } if s.PtrFloat != nil { fmt.Printf(formatPointer, "PtrFloat", *s.PtrFloat) } else { fmt.Printf(format, "PtrFloat", s.PtrFloat) } if s.PtrComplex != nil { fmt.Printf(formatPointer, "PtrComplex", *s.PtrComplex) } else { fmt.Printf(format, "PtrComplex", s.PtrComplex) } if s.PtrError != nil { fmt.Printf(formatPointer, "PtrError", *s.PtrError) } else { fmt.Printf(format, "PtrError", s.PtrError) } if s.PtrTime != nil { fmt.Printf(formatPointer, "PtrTime", *s.PtrTime) } else { fmt.Printf(format, "PtrTime", s.PtrTime) } if s.PtrDuration != nil { fmt.Printf(formatPointer, "PtrDuration", *s.PtrDuration) } else { fmt.Printf(format, "PtrDuration", s.PtrDuration) } if s.PtrNestedStruct != nil { fmt.Printf(formatPtrStruct, "PtrNestedStruct", *s.PtrNestedStruct) } else { fmt.Printf(formatStruct, "PtrNestedStruct", s.PtrNestedStruct) } fmt.Printf(format, "MapString", s.MapString) fmt.Printf(format, "MapBool", s.MapBool) fmt.Printf(format, "MapInt", s.MapInt) fmt.Printf(format, "MapUint", s.MapUint) fmt.Printf(format, "MapFloat", s.MapFloat) fmt.Printf(format, "MapComplex", s.MapComplex) fmt.Printf(format, "MapInterface", s.MapInterface) fmt.Printf(format, "SliceString", s.SliceString) fmt.Printf(format, "SliceBool", s.SliceBool) fmt.Printf(format, "SliceInt", s.SliceInt) fmt.Printf(format, "SliceUint", s.SliceUint) fmt.Printf(format, "SliceFloat", s.SliceFloat) fmt.Printf(format, "SliceComplex", s.SliceComplex) fmt.Printf(format, "SliceInterface", s.SliceInterface) { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrString { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrString", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrBool { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrBool", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrInt { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrInt", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrUint { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrUint", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrFloat { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrFloat", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrComplex { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrComplex", m) } fmt.Printf(format, "Hidden", s.Hidden) fmt.Printf(format, "unexported", s.unexported) } func main() { t := structX s, err := structs.New(&t) if err != nil { fmt.Printf("New[Error]: %v.\n", err) return } for _, name := range structFieldNames { err := s.Field(name).SetZero() if err != nil { fmt.Printf("SetZero[Error]: %v.\n", err) } } printStruct(&t) }
Output: SetZero[Error]: could not set field structTest.unexported to zero-value: struct field is not settable. - String: . - Bool: false. - Int: 0. - Uint: 0. - Float: 0. - Complex: (0+0i). - Bytes: . - Interface: <nil>. - Error: <nil>. - Time: 0001-01-01 00:00:00 +0000 UTC. - Duration: 0s. - NestedStruct: {Uint:0 String:}. - PtrString: <nil>. - PtrBool: <nil>. - PtrInt: <nil>. - PtrUint: <nil>. - PtrFloat: <nil>. - PtrComplex: <nil>. - PtrError: <nil>. - PtrTime: <nil>. - PtrDuration: <nil>. - PtrNestedStruct: <nil>. - MapString: map[]. - MapBool: map[]. - MapInt: map[]. - MapUint: map[]. - MapFloat: map[]. - MapComplex: map[]. - MapInterface: map[]. - SliceString: []. - SliceBool: []. - SliceInt: []. - SliceUint: []. - SliceFloat: []. - SliceComplex: []. - SliceInterface: []. - SlicePtrString: []. - SlicePtrBool: []. - SlicePtrInt: []. - SlicePtrUint: []. - SlicePtrFloat: []. - SlicePtrComplex: []. - Hidden: . - unexported: false.
Example (ZeroToValue) ¶
package main import ( "fmt" "time" "github.com/pkg/errors" "github.com/roninzo/pointers" "github.com/roninzo/structs" ) type structTest struct { String string `json:"string,omitempty"` Bool bool `json:"bool,omitempty"` Int int `json:"int,omitempty"` Uint uint `json:"uint,omitempty"` Float float32 `json:"float,omitempty"` Complex complex128 `json:"complex,omitempty"` Bytes []byte `json:"bytes,omitempty"` Interface interface{} `json:"interface,omitempty"` Error error `json:"error,omitempty"` Time time.Time `json:"time,omitempty"` Duration time.Duration `json:"duration,omitempty"` NestedStruct structNested `json:"nested_struct,omitempty"` PtrString *string `json:"pointer_string,omitempty"` PtrBool *bool `json:"pointer_bool,omitempty"` PtrInt *int `json:"pointer_int,omitempty"` PtrUint *uint `json:"pointer_uint,omitempty"` PtrFloat *float32 `json:"pointer_float,omitempty"` PtrComplex *complex128 `json:"pointer_complex,omitempty"` PtrError *error `json:"pointer_error,omitempty"` PtrTime *time.Time `json:"pointer_time,omitempty"` PtrDuration *time.Duration `json:"pointer_duration,omitempty"` PtrNestedStruct *structNested `json:"pointer_nested_struct,omitempty"` MapString map[string]string `json:"map_string,omitempty"` MapBool map[string]bool `json:"map_bool,omitempty"` MapInt map[string]int `json:"mapint,omitempty"` MapUint map[string]uint `json:"map_uint,omitempty"` MapFloat map[string]float32 `json:"map_float,omitempty"` MapComplex map[string]complex128 `json:"map_complex,omitempty"` MapInterface map[string]interface{} `json:"map_interface,omitempty"` SliceString []string `json:"slice_string,omitempty"` SliceBool []bool `json:"slice_bool,omitempty"` SliceInt []int `json:"slice_int,omitempty"` SliceUint []uint `json:"slice_uint,omitempty"` SliceFloat []float32 `json:"slice_float,omitempty"` SliceComplex []complex128 `json:"slice_complex,omitempty"` SliceInterface []interface{} `json:"slice_interface,omitempty"` SlicePtrString []*string `json:"slice_pointer_string,omitempty"` SlicePtrBool []*bool `json:"slice_pointer_bool,omitempty"` SlicePtrInt []*int `json:"slice_pointer_int,omitempty"` SlicePtrUint []*uint `json:"slice_pointer_uint,omitempty"` SlicePtrFloat []*float32 `json:"slice_pointer_float,omitempty"` SlicePtrComplex []*complex128 `json:"slice_pointer_complex,omitempty"` Hidden string `json:"-"` unexported bool } type structNested struct { Uint uint `json:"uint,omitempty"` String string `json:"string,omitempty"` } var structV structTest = structTest{ String: "Roninzo", Bool: true, Int: 8, Uint: uint(123456), Float: 1922.50, Complex: complex(22, 50), Bytes: []byte("Hello world"), Interface: "anything", Error: errors.New("rows not found"), Time: time.Date(2021, time.August, 3, 16, 44, 46, 0, time.UTC), Duration: 5 * time.Second, NestedStruct: structNested{Uint: 122334, String: "Apache"}, PtrString: pointers.String("Roninzo"), PtrBool: pointers.Bool(true), PtrInt: pointers.Int(8), PtrUint: pointers.Uint(uint(123456)), PtrFloat: pointers.Float32(1922.50), PtrComplex: pointers.Complex128(complex(22, 50)), PtrError: pointers.Error(errors.New("rows not found")), PtrTime: pointers.Time(time.Date(2021, time.August, 3, 16, 44, 46, 0, time.UTC)), PtrDuration: pointers.Duration(5 * time.Second), PtrNestedStruct: &structNested{Uint: 122334, String: "Apache"}, MapString: map[string]string{"A": "one", "B": "two", "C": "three"}, MapBool: map[string]bool{"A": true, "B": false}, MapInt: map[string]int{"A": 1, "B": 2, "C": 3}, MapUint: map[string]uint{"A": uint(1), "B": uint(2), "C": uint(3)}, MapFloat: map[string]float32{"A": 1.1, "B": 1.2, "C": 1.3}, MapComplex: map[string]complex128{"A": complex(1, 1), "B": complex(1, 2), "C": complex(1, 3)}, MapInterface: map[string]interface{}{"A": 1, "B": "two", "C": 3.0}, SliceString: []string{"one", "two", "three"}, SliceBool: []bool{true, false}, SliceInt: []int{1, 2, 3}, SliceUint: []uint{uint(1), uint(2), uint(3)}, SliceFloat: []float32{1.1, 1.2, 1.3}, SliceComplex: []complex128{complex(1, 1), complex(1, 2), complex(1, 3)}, SliceInterface: []interface{}{1, "two", 3.0}, SlicePtrString: []*string{pointers.String("one"), pointers.String("two"), pointers.String("three")}, SlicePtrBool: []*bool{pointers.Bool(true), pointers.Bool(false)}, SlicePtrInt: []*int{pointers.Int(1), pointers.Int(2), pointers.Int(3)}, SlicePtrUint: []*uint{pointers.Uint(uint(1)), pointers.Uint(uint(2)), pointers.Uint(uint(3))}, SlicePtrFloat: []*float32{pointers.Float32(1.1), pointers.Float32(1.2), pointers.Float32(1.3)}, SlicePtrComplex: []*complex128{pointers.Complex128(complex(1, 1)), pointers.Complex128(complex(1, 2)), pointers.Complex128(complex(1, 3))}, Hidden: "abcdefg", unexported: true, } func printStruct(s *structTest) { format := "- %15s: %v.\n" formatStruct := "- %15s: %+v.\n" formatPointer := "- %15s: *%v.\n" formatPtrStruct := "- %15s: *%+v.\n" fmt.Printf(format, "String", s.String) fmt.Printf(format, "Bool", s.Bool) fmt.Printf(format, "Int", s.Int) fmt.Printf(format, "Uint", s.Uint) fmt.Printf(format, "Float", s.Float) fmt.Printf(format, "Complex", s.Complex) fmt.Printf(format, "Bytes", string(s.Bytes)) fmt.Printf(format, "Interface", s.Interface) fmt.Printf(format, "Error", s.Error) fmt.Printf(format, "Time", s.Time) fmt.Printf(format, "Duration", s.Duration) fmt.Printf(formatStruct, "NestedStruct", s.NestedStruct) if s.PtrString != nil { fmt.Printf(formatPointer, "PtrString", *s.PtrString) } else { fmt.Printf(format, "PtrString", s.PtrString) } if s.PtrBool != nil { fmt.Printf(formatPointer, "PtrBool", *s.PtrBool) } else { fmt.Printf(format, "PtrBool", s.PtrBool) } if s.PtrInt != nil { fmt.Printf(formatPointer, "PtrInt", *s.PtrInt) } else { fmt.Printf(format, "PtrInt", s.PtrInt) } if s.PtrUint != nil { fmt.Printf(formatPointer, "PtrUint", *s.PtrUint) } else { fmt.Printf(format, "PtrUint", s.PtrUint) } if s.PtrFloat != nil { fmt.Printf(formatPointer, "PtrFloat", *s.PtrFloat) } else { fmt.Printf(format, "PtrFloat", s.PtrFloat) } if s.PtrComplex != nil { fmt.Printf(formatPointer, "PtrComplex", *s.PtrComplex) } else { fmt.Printf(format, "PtrComplex", s.PtrComplex) } if s.PtrError != nil { fmt.Printf(formatPointer, "PtrError", *s.PtrError) } else { fmt.Printf(format, "PtrError", s.PtrError) } if s.PtrTime != nil { fmt.Printf(formatPointer, "PtrTime", *s.PtrTime) } else { fmt.Printf(format, "PtrTime", s.PtrTime) } if s.PtrDuration != nil { fmt.Printf(formatPointer, "PtrDuration", *s.PtrDuration) } else { fmt.Printf(format, "PtrDuration", s.PtrDuration) } if s.PtrNestedStruct != nil { fmt.Printf(formatPtrStruct, "PtrNestedStruct", *s.PtrNestedStruct) } else { fmt.Printf(formatStruct, "PtrNestedStruct", s.PtrNestedStruct) } fmt.Printf(format, "MapString", s.MapString) fmt.Printf(format, "MapBool", s.MapBool) fmt.Printf(format, "MapInt", s.MapInt) fmt.Printf(format, "MapUint", s.MapUint) fmt.Printf(format, "MapFloat", s.MapFloat) fmt.Printf(format, "MapComplex", s.MapComplex) fmt.Printf(format, "MapInterface", s.MapInterface) fmt.Printf(format, "SliceString", s.SliceString) fmt.Printf(format, "SliceBool", s.SliceBool) fmt.Printf(format, "SliceInt", s.SliceInt) fmt.Printf(format, "SliceUint", s.SliceUint) fmt.Printf(format, "SliceFloat", s.SliceFloat) fmt.Printf(format, "SliceComplex", s.SliceComplex) fmt.Printf(format, "SliceInterface", s.SliceInterface) { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrString { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrString", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrBool { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrBool", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrInt { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrInt", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrUint { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrUint", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrFloat { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrFloat", m) } { m := make([]interface{}, 0) for _, ptr := range s.SlicePtrComplex { if ptr != nil { v := fmt.Sprintf("*%v", *ptr) m = append(m, v) continue } m = append(m, nil) } fmt.Printf(format, "SlicePtrComplex", m) } fmt.Printf(format, "Hidden", s.Hidden) fmt.Printf(format, "unexported", s.unexported) } func main() { t := structTest{} s, err := structs.New(&t) if err != nil { fmt.Printf("New[Error]: %v.\n", err) return } err = s.Field("String").Set(structV.String) err = s.Field("Bool").Set(structV.Bool) err = s.Field("Int").Set(structV.Int) err = s.Field("Uint").Set(structV.Uint) err = s.Field("Float").Set(structV.Float) err = s.Field("Complex").Set(structV.Complex) err = s.Field("Bytes").Set(structV.Bytes) err = s.Field("Interface").Set(structV.Interface) err = s.Field("Error").Set(structV.Error) err = s.Field("Time").Set(structV.Time) err = s.Field("Duration").Set(structV.Duration) err = s.Field("NestedStruct").Set(structV.NestedStruct) err = s.Field("PtrString").Set(structV.PtrString) err = s.Field("PtrBool").Set(structV.PtrBool) err = s.Field("PtrInt").Set(structV.PtrInt) err = s.Field("PtrUint").Set(structV.PtrUint) err = s.Field("PtrFloat").Set(structV.PtrFloat) err = s.Field("PtrComplex").Set(structV.PtrComplex) err = s.Field("PtrError").Set(structV.PtrError) err = s.Field("PtrTime").Set(structV.PtrTime) err = s.Field("PtrDuration").Set(structV.PtrDuration) err = s.Field("PtrNestedStruct").Set(structV.PtrNestedStruct) err = s.Field("MapString").Set(structV.MapString) err = s.Field("MapBool").Set(structV.MapBool) err = s.Field("MapInt").Set(structV.MapInt) err = s.Field("MapUint").Set(structV.MapUint) err = s.Field("MapFloat").Set(structV.MapFloat) err = s.Field("MapComplex").Set(structV.MapComplex) err = s.Field("MapInterface").Set(structV.MapInterface) err = s.Field("SliceString").Set(structV.SliceString) err = s.Field("SliceBool").Set(structV.SliceBool) err = s.Field("SliceInt").Set(structV.SliceInt) err = s.Field("SliceUint").Set(structV.SliceUint) err = s.Field("SliceFloat").Set(structV.SliceFloat) err = s.Field("SliceComplex").Set(structV.SliceComplex) err = s.Field("SliceInterface").Set(structV.SliceInterface) err = s.Field("SlicePtrString").Set(structV.SlicePtrString) err = s.Field("SlicePtrBool").Set(structV.SlicePtrBool) err = s.Field("SlicePtrInt").Set(structV.SlicePtrInt) err = s.Field("SlicePtrUint").Set(structV.SlicePtrUint) err = s.Field("SlicePtrFloat").Set(structV.SlicePtrFloat) err = s.Field("SlicePtrComplex").Set(structV.SlicePtrComplex) err = s.Field("Hidden").Set(structV.Hidden) err = s.Field("unexported").Set(structV.unexported) if err != nil { fmt.Printf("Set[Error]: %v.\n", err) } printStruct(&t) }
Output: Set[Error]: could not set field structTest.unexported: struct field is not settable. - String: Roninzo. - Bool: true. - Int: 8. - Uint: 123456. - Float: 1922.5. - Complex: (22+50i). - Bytes: Hello world. - Interface: anything. - Error: rows not found. - Time: 2021-08-03 16:44:46 +0000 UTC. - Duration: 5s. - NestedStruct: {Uint:122334 String:Apache}. - PtrString: *Roninzo. - PtrBool: *true. - PtrInt: *8. - PtrUint: *123456. - PtrFloat: *1922.5. - PtrComplex: *(22+50i). - PtrError: *rows not found. - PtrTime: *2021-08-03 16:44:46 +0000 UTC. - PtrDuration: *5s. - PtrNestedStruct: *{Uint:122334 String:Apache}. - MapString: map[A:one B:two C:three]. - MapBool: map[A:true B:false]. - MapInt: map[A:1 B:2 C:3]. - MapUint: map[A:1 B:2 C:3]. - MapFloat: map[A:1.1 B:1.2 C:1.3]. - MapComplex: map[A:(1+1i) B:(1+2i) C:(1+3i)]. - MapInterface: map[A:1 B:two C:3]. - SliceString: [one two three]. - SliceBool: [true false]. - SliceInt: [1 2 3]. - SliceUint: [1 2 3]. - SliceFloat: [1.1 1.2 1.3]. - SliceComplex: [(1+1i) (1+2i) (1+3i)]. - SliceInterface: [1 two 3]. - SlicePtrString: [*one *two *three]. - SlicePtrBool: [*true *false]. - SlicePtrInt: [*1 *2 *3]. - SlicePtrUint: [*1 *2 *3]. - SlicePtrFloat: [*1.1 *1.2 *1.3]. - SlicePtrComplex: [*(1+1i) *(1+2i) *(1+3i)]. - Hidden: abcdefg. - unexported: false.
func (*StructField) SetBool ¶
func (f *StructField) SetBool(x bool)
SetBool sets the field to the bool value x. Unsettable struct fields will return an error.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Enabled bool `json:"enabled,omitempty"` } server := Server{ Enabled: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f := s.Field("Enabled") if f.CanBool() { fmt.Printf("Bool: %v.\n", f.Bool()) f.SetBool(false) fmt.Printf("SetBool: %v.\n", f.Bool()) } }
Output: Bool: true. SetBool: false.
func (*StructField) SetBytes ¶
func (f *StructField) SetBytes(x []byte)
SetBytes sets the field to the slice of bytes value x. Unsettable struct fields will return an error.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Stream []byte `json:"stream,omitempty"` } server := Server{ Stream: []byte("Hello world"), } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f := s.Field("Stream") if f.CanBytes() { b := f.Bytes() fmt.Printf("Bytes: %v.\n", b) fmt.Printf("BytesString: %v.\n", string(b)) f.SetBytes([]byte("Bye bye world")) b = f.Bytes() fmt.Printf("SetBytes: %v.\n", b) fmt.Printf("SetBytesString: %v.\n", string(b)) } }
Output: Bytes: [72 101 108 108 111 32 119 111 114 108 100]. BytesString: Hello world. SetBytes: [66 121 101 32 98 121 101 32 119 111 114 108 100]. SetBytesString: Bye bye world.
func (*StructField) SetComplex ¶
func (f *StructField) SetComplex(x complex128)
SetComplex sets the field to the complex128 value x. Unsettable struct fields will return an error.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Complex complex128 `json:"complex,omitempty"` } server := Server{ Complex: complex(22, 50), } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f := s.Field("Complex") if f.CanComplex() { fmt.Printf("Complex: %v.\n", f.Complex()) f.SetComplex(complex(77, 2)) fmt.Printf("SetComplex: %v.\n", f.Complex()) } }
Output: Complex: (22+50i). SetComplex: (77+2i).
func (*StructField) SetDuration ¶
func (f *StructField) SetDuration(x time.Duration)
SetDuration sets the field to the time.Duration value x. Unsettable struct fields will return an error.
Example ¶
package main import ( "fmt" "time" "github.com/roninzo/structs" ) func main() { type Server struct { TimeOut time.Duration `json:"time_out,omitempty"` } server := Server{ TimeOut: 5 * time.Second, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f := s.Field("TimeOut") if f.CanDuration() { fmt.Printf("Duration: %v.\n", f.Duration()) f.SetDuration(30 * time.Second) fmt.Printf("SetDuration: %v.\n", f.Duration()) } }
Output: Duration: 5s. SetDuration: 30s.
func (*StructField) SetError ¶
func (f *StructField) SetError(x error)
SetError sets the field to the error value x. Unsettable struct fields will return an error.
Example ¶
package main import ( "fmt" "github.com/pkg/errors" "github.com/roninzo/structs" ) func main() { type Server struct { Err error `json:"err,omitempty"` } server := Server{ Err: errors.New("rows not found"), } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f := s.Field("Err") if f.CanError() { fmt.Printf("Error: %v.\n", f.Error()) err := errors.Wrap(f.Error(), "empty table") f.SetError(err) fmt.Printf("SetError: %v.\n", f.Error()) } }
Output: Error: rows not found. SetError: empty table: rows not found.
func (*StructField) SetFloat ¶
func (f *StructField) SetFloat(x float64)
SetFloat sets the field to the float64 value x. Unsettable struct fields will return an error.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Price float32 `json:"price,omitempty"` } server := Server{ Price: 22.50, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f := s.Field("Price") if f.CanFloat() { fmt.Printf("Float: %v.\n", f.Float()) f.SetFloat(450.50) fmt.Printf("SetUint: %v.\n", f.Float()) } }
Output: Float: 22.5. SetUint: 450.5.
func (*StructField) SetInt ¶
func (f *StructField) SetInt(x int64)
SetInt sets the field to the int64 value x. Unsettable struct fields will return an error.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Count int `json:"count,omitempty"` } server := Server{ Count: 123456, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f := s.Field("Count") if f.CanInt() { fmt.Printf("Int: %v.\n", f.Int()) f.SetInt(654321) fmt.Printf("SetInt: %v.\n", f.Int()) } }
Output: Int: 123456. SetInt: 654321.
func (*StructField) SetInterface ¶
func (f *StructField) SetInterface(x interface{})
SetInterface sets the field to the interface value x. Unsettable struct fields will return an error.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Anything interface{} `json:"anything,omitempty"` } server := Server{ Anything: 654321, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f := s.Field("Anything") if f.CanInterface() { fmt.Printf("Interface: %v.\n", f.Interface()) f.SetInterface(123456) fmt.Printf("SetInterface: %v.\n", f.Interface()) } }
Output: Interface: 654321. SetInterface: 123456.
func (*StructField) SetNil ¶
func (f *StructField) SetNil() error
SetNil sets the field to its zero value. Unsettable/Un-nillable struct fields will return an error.
func (*StructField) SetString ¶
func (f *StructField) SetString(x string)
SetString sets the field to the string value x. Unsettable struct fields will return an error.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` } server := Server{ Name: "Roninzo", } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f := s.Field("Name") if f.CanString() { fmt.Printf("String: %v.\n", f.String()) f.SetString("ozninoR") fmt.Printf("SetString: %v.\n", f.String()) } }
Output: String: Roninzo. SetString: ozninoR.
func (*StructField) SetStruct ¶
func (f *StructField) SetStruct(x *StructValue)
SetStruct sets the field to the StructValue value x. Unsettable struct fields will return an error.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Program struct { Name string `json:"name,omitempty"` } type Server struct { Program *Program `json:"program,omitempty"` } program := Program{ Name: "Apache", } server := Server{ Program: &program, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f := s.Field("Program") if f.CanStruct() { fmt.Printf("Struct: %v.\n", server.Program.Name) program2 := Program{ Name: "Microsoft IIS", } p, err := structs.New(&program2) if err != nil { fmt.Printf("Error: %v\n", err) } f.SetStruct(p) fmt.Printf("SetStruct: %v.\n", server.Program.Name) } }
Output: Struct: Apache. SetStruct: Microsoft IIS.
func (*StructField) SetTime ¶
func (f *StructField) SetTime(x time.Time)
SetTime sets the field to the time.Time value x. Unsettable struct fields will return an error.
Example ¶
package main import ( "fmt" "time" "github.com/roninzo/structs" ) func main() { type Server struct { ChangedAt time.Time `json:"changed_at,omitempty"` } server := Server{ ChangedAt: time.Date(2021, time.August, 3, 16, 44, 46, 0, time.UTC), } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f := s.Field("ChangedAt") if f.CanTime() { fmt.Printf("Time: %v.\n", f.Time()) t := time.Date(2021, time.August, 31, 12, 30, 11, 0, time.UTC) f.SetTime(t) fmt.Printf("SetTime: %v.\n", f.Time()) } }
Output: Time: 2021-08-03 16:44:46 +0000 UTC. SetTime: 2021-08-31 12:30:11 +0000 UTC.
func (*StructField) SetUint ¶
func (f *StructField) SetUint(x uint64)
SetUint sets the field to the uint64 value x. Unsettable struct fields will return an error.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { ID uint `json:"id,omitempty"` } server := Server{ ID: 123456, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f := s.Field("ID") if f.CanUint() { fmt.Printf("Uint: %v.\n", f.Uint()) f.SetUint(654321) fmt.Printf("SetUint: %v.\n", f.Uint()) } }
Output: Uint: 123456. SetUint: 654321.
func (*StructField) SetZero ¶
func (f *StructField) SetZero() error
SetZero sets the field to its zero value. Unsettable struct fields will return an error.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Count") f3 := s.Field("unexported") fmt.Printf("Value: %v.\n", f1.Value()) fmt.Printf("Value: %v.\n", f2.Value()) fmt.Printf("Value: %v.\n", f3.Value()) err1 := f1.SetZero() err2 := f2.SetZero() err3 := f3.SetZero() fmt.Printf("SetZero: %v.\n", f1.Value()) fmt.Printf("SetZero: %v.\n", f2.Value()) fmt.Printf("SetZero: %v.\n", f3.Value()) fmt.Printf("Error: %v.\n", err1) fmt.Printf("Error: %v.\n", err2) fmt.Printf("Error: %v.\n", err3) }
Output: Value: Roninzo. Value: 0. Value: false. SetZero: . SetZero: 0. SetZero: false. Error: <nil>. Error: <nil>. Error: could not set field Server.unexported to zero-value: struct field is not settable.
func (*StructField) String ¶
func (f *StructField) String() string
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field("ID") f2 := s.Field("Name") if f1.CanString() { fmt.Printf("String: %v.\n", f1.String()) } if f2.CanString() { fmt.Printf("String: %v.\n", f2.String()) } }
Output: String: Roninzo.
func (*StructField) Struct ¶
func (f *StructField) Struct() *StructValue
Struct returns nested struct from field or nil if f is not a nested struct.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Program struct { Name string `json:"name,omitempty"` } type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` Program Program `json:"program,omitempty"` } program := Program{ Name: "Apache", } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", Program: program, } s1, _ := structs.New(&server) s2 := s1.Field("Program").Struct() fmt.Printf("Struct: %v\n", s1.Name()) fmt.Printf("Struct: %v\n", s2.Name()) }
Output: Struct: Server Struct: Program
func (*StructField) Tag ¶
func (f *StructField) Tag(key string) (string, bool)
Tag returns the value associated with key in the tag string. If the key is present in the tag the value (which may be empty) is returned. Otherwise the returned value will be the empty string. The ok return value reports whether the value was explicitly set in the tag string.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } t1, _ := s.Field(0).Tag("json") t2, _ := s.Field("Enabled").Tag("json") fmt.Printf("Tag: %v\n", t1) fmt.Printf("Tag: %v\n", t2) }
Output: Tag: name,omitempty Tag: enabled,omitempty
func (*StructField) Time ¶
func (f *StructField) Time() time.Time
Example ¶
package main import ( "fmt" "time" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` ChangedAt time.Time `json:"changed_at,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, ChangedAt: time.Date(2021, time.August, 3, 16, 44, 46, 0, time.UTC), Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("ChangedAt") if f1.CanTime() { fmt.Printf("Time: %v\n", f1.Time()) } if f2.CanTime() { fmt.Printf("Time: %v\n", f2.Time()) } }
Output: Time: 2021-08-03 16:44:46 +0000 UTC
func (*StructField) Type ¶
func (f *StructField) Type() reflect.Type
Type returns the underlying type of the field.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Enabled") fmt.Printf("Type: %v\n", s.Type()) fmt.Printf("Type: %v\n", f1.Type()) fmt.Printf("Type: %v\n", f2.Type()) }
Output: Type: structs_test.Server Type: string Type: bool
func (*StructField) Uint ¶
func (f *StructField) Uint() uint64
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("ID") if f1.CanUint() { fmt.Printf("Uint: %v\n", f1.Uint()) } if f2.CanUint() { fmt.Printf("Uint: %v\n", f2.Uint()) } }
Output: Uint: 123456
func (*StructField) Value ¶
func (f *StructField) Value() reflect.Value
Value returns the underlying value of the field. Unexported struct fields will be neglected.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Enabled") fmt.Printf("Value: %v\n", f1.Value()) fmt.Printf("Value: %v\n", f2.Value()) }
Output: Value: Roninzo Value: true
func (*StructField) Zero ¶
func (f *StructField) Zero() reflect.Value
Zero returns field's type specific zero value. For instance, the zero-value of a string field is "", of an int is 0, and so on.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 5, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field("Enabled") f2 := s.Field("Count") fmt.Printf("Zero: %v\n", f1.Zero()) fmt.Printf("Zero: %v\n", f2.Zero()) }
Output: Zero: false Zero: 0
type StructFields ¶
type StructFields []*StructField
StructFields represents all struct fields that encapsulates high level functions around the struct fields.
func Fields ¶
func Fields(dest interface{}) (StructFields, error)
Fields returns a slice of *StructField. For more info refer to StructValue types Fields() method. It returns an error if s's kind is not struct.
func (StructFields) Names ¶
func (fields StructFields) Names() []string
Names returns all the field names of the struct. This method is not recursive, which means that nested structs must be dealt with explicitly.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Module struct { Name string `json:"name"` } type Server struct { Name *string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` unexported bool Module *Module `json:"module"` } var name string = "Roninzo" server := Server{ Name: &name, ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", unexported: true, Module: &Module{Name: "Power Supply"}, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } fmt.Printf("Fields.Names: %v\n", s.Fields().Names()) }
Output: Fields.Names: [Name ID Enabled Count Password unexported Module]
func (StructFields) Parent ¶
func (fields StructFields) Parent() *StructValue
Parent returns the related StructValue object (which is a level above StructFields).
type StructRows ¶
type StructRows struct { StructValue // embedded copy and inherits all fields and methods. // contains filtered or unexported fields }
StructRows represents a single row of a struct from a StructValue containing a slice of structs. If StructValue does not contain a slice of structs, StructRows cannot be initialized by contructor Rows. StructRows encapsulates high level functions around the element of slice of structs.
func (*StructRows) Close ¶
func (r *StructRows) Close() error
Close closes the Rows, preventing further enumeration. If Next is called and returns false and there are no further result rows, the Rows are closed automatically and it will suffice to check the result of Err. Close is idempotent and does not affect the result of Err.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Count int32 `json:"count,omitempty"` } servers := []Server{ {Count: 5}, {Count: 6}, } s, err := structs.New(&servers) if err != nil { fmt.Printf("New[Error]: %v.\n", err) } rows, err := s.Rows() if err != nil { fmt.Printf("Rows[Error]: %v.\n", err) } for rows.Next() { fmt.Printf("struct row index: %d.\n", rows.Index()) } err = rows.Close() if err != nil { fmt.Printf("Close[Error]: %v.\n", err) } fmt.Printf("struct row index: %d.\n", rows.Index()) if err := rows.Err(); err != nil { fmt.Printf("Err[Error]: %v.\n", err) } }
Output: struct row index: 0. struct row index: 1. struct row index: -1.
func (*StructRows) Columns ¶
func (r *StructRows) Columns() ([]string, error)
Columns returns the current struct field names. Columns returns an error if the rows are closed.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Count int32 `json:"count,omitempty"` } servers := []Server{ {Count: 5}, {Count: 6}, } s, err := structs.New(&servers) if err != nil { fmt.Printf("New[Error]: %v.\n", err) } rows, err := s.Rows() if err != nil { fmt.Printf("Rows[Error]: %v.\n", err) } cols, err := rows.Columns() if err != nil { fmt.Printf("Columns[Error]: %v.\n", err) } else { fmt.Printf("struct row column names: %s.\n", cols) } err = rows.Close() if err != nil { fmt.Printf("Close[Error]: %v.\n", err) } cols, err = rows.Columns() if err != nil { fmt.Printf("Columns[Error]: %v.\n", err) } else { fmt.Printf("struct row column names: %s.\n", cols) } if err := rows.Err(); err != nil { fmt.Printf("Err[Error]: %v.\n", err) } }
Output: struct row column names: [Count]. Columns[Error]: struct rows are closed.
func (*StructRows) Err ¶
func (r *StructRows) Err() (err error)
Err returns the error, if any, that was encountered during iteration. Err may be called after an explicit or implicit Close.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Count int32 `json:"count,omitempty"` } servers := []Server{ {Count: 5}, {Count: 6}, } s, err := structs.New(&servers) if err != nil { fmt.Printf("New[Error]: %v.\n", err) } rows, err := s.Rows() if err != nil { fmt.Printf("Err[Error]: %v.\n", err) } defer rows.Close() fmt.Printf("struct row index: %d.\n", rows.Index()) _ = rows.Field("InvalidName") if err := rows.Err(); err != nil { fmt.Printf("Err[Error]: %v.\n", err) } }
Output: struct row index: -1. Err[Error]: invalid field name InvalidName.
func (*StructRows) Index ¶
func (r *StructRows) Index() int
Index returns the index element in the slice of structs pointing to current struct. Index returns OutOfRange, i.e. -1, if the rows are closed.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Count int32 `json:"count,omitempty"` } servers := []Server{ {Count: 5}, {Count: 6}, } s, err := structs.New(&servers) if err != nil { fmt.Printf("New[Error]: %v.\n", err) } rows, err := s.Rows() if err != nil { fmt.Printf("Rows[Error]: %v.\n", err) } for rows.Next() { fmt.Printf("struct row index: %d.\n", rows.Index()) } err = rows.Close() if err != nil { fmt.Printf("Close[Error]: %v.\n", err) } fmt.Printf("struct row index: %d.\n", rows.Index()) if err := rows.Err(); err != nil { fmt.Printf("Err[Error]: %v.\n", err) } }
Output: struct row index: 0. struct row index: 1. struct row index: -1.
func (*StructRows) Len ¶
func (r *StructRows) Len() int
Len returns the number elements in the slice of structs. Len returns OutOfRange, i.e. -1, if the rows are closed.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Count int32 `json:"count,omitempty"` } servers := []Server{ {Count: 5}, {Count: 6}, } s, err := structs.New(&servers) if err != nil { fmt.Printf("New[Error]: %v.\n", err) } rows, err := s.Rows() if err != nil { fmt.Printf("Rows[Error]: %v.\n", err) } fmt.Printf("struct number of rows: %d.\n", rows.Len()) err = rows.Close() if err != nil { fmt.Printf("Close[Error]: %v.\n", err) } fmt.Printf("struct number of rows: %d.\n", rows.Len()) if err := rows.Err(); err != nil { fmt.Printf("Err[Error]: %v.\n", err) } }
Output: struct number of rows: 2. struct number of rows: -1.
func (*StructRows) MaxRow ¶
func (r *StructRows) MaxRow() int
MaxRow returns the index of the lasr elements in the slice of structs. MaxRow returns OutOfRange, i.e. -1, if the rows are closed.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Count int32 `json:"count,omitempty"` } servers := []Server{ {Count: 5}, {Count: 6}, } s, err := structs.New(&servers) if err != nil { fmt.Printf("New[Error]: %v.\n", err) } rows, err := s.Rows() if err != nil { fmt.Printf("Rows[Error]: %v.\n", err) } fmt.Printf("struct last row index: %d.\n", rows.MaxRow()) err = rows.Close() if err != nil { fmt.Printf("Close[Error]: %v.\n", err) } fmt.Printf("struct last row index: %d.\n", rows.MaxRow()) if err := rows.Err(); err != nil { fmt.Printf("Err[Error]: %v.\n", err) } }
Output: struct last row index: 1. struct last row index: -1.
func (*StructRows) Next ¶
func (r *StructRows) Next() bool
Next prepares the next result row for reading an element from the slice of struct. It returns true on success, or false if there is no next result row or an error happened while preparing it. Err should be consulted to distinguish between the two cases.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Count int32 `json:"count,omitempty"` } servers := []Server{ {Count: 5}, {Count: 6}, } s, err := structs.New(&servers) if err != nil { fmt.Printf("New[Error]: %v.\n", err) } rows, err := s.Rows() if err != nil { fmt.Printf("Rows[Error]: %v.\n", err) } for rows.Next() { fmt.Printf("struct row index: %d.\n", rows.Index()) } err = rows.Close() if err != nil { fmt.Printf("Close[Error]: %v.\n", err) } fmt.Printf("struct row index: %d.\n", rows.Index()) if err := rows.Err(); err != nil { fmt.Printf("Err[Error]: %v.\n", err) } }
Output: struct row index: 0. struct row index: 1. struct row index: -1.
type StructValue ¶
type StructValue struct { Parent *StructValue // Parent struct, if nested struct. Error error // Error added when struct could not be found. // contains filtered or unexported fields }
StructValue is the representation of a Go struct powered by the Go reflection package. Its interface provides field getters, field setters and much more.
func IndirectStruct ¶ added in v1.0.5
func IndirectStruct(v reflect.Value) *StructValue
IndirectStruct finds the struct or structs in the interface dest.
Types Description Example T a struct New(t) *T a pointer to a struct New(&t) []T a slice of struct New([]T{t}) *[]T a pointer to a slice of struct New(&[]T{t}) []*T a slice of pointers to struct New([]*T{&t})
Similar to utils.CanStruct(v)
func New ¶
func New(dest interface{}, parents ...*StructValue) (*StructValue, error)
New returns a new StructValue initialized to the struct concrete value stored in the interface dest. New(nil) returns the StructValue with an error.
BUG(roninzo): the New method behaves unexpectidely when passing in an empty slice of pointers to structs.
StructValue.New
StructValue.findStruct(v, t) => IndirectStruct StructValue.getElem(v, t) => IndirectValueAndType utils.StructValueElem(v, t)
TODEL: New Load parent StructValue, if any.
TODEL: findStruct findStruct finds where the struct is inside the reflect value and type. By being chainable, findStruct uses withStruct to finalize successful completion and exit the switch case below, all in a one-liner, otherwise it returns the StructValue explictly at the end. See the Support paragraph in the documentation for more details.
TODEL: withStruct withStruct returns StructValue object after setting reflect.Value of struct found. By being chainable, withStruct can finalize StructValue and return it at the same time.
TODEL: getElem getElem returns the element or the first element of the reflection pointer value and type. It saves an errors inside StructValue if the type's Kind is not Array, Ptr, or Slice.
TODEL: appendKind appendKind appends reflect type t to the slice of kinds in StructValue. The first, it initialized kinds as a the slice of kinds.
TODEL: utils.StructValueElem StructValueElem follows the pointer v and returns the element it points to, for borth reflect value and reflect type, as well as nil error. If v is not a pointer or not a supported pointer, it returns zero-value reflect value and reflect type as well as an error.
MIGRATE: utils.CanStruct CanStruct returns true if reflect value represents a nested struct, else returns false.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type T struct { String string Uint uint Bool bool Int int32 } t := T{ String: "Roninzo", Uint: 123456, Bool: true, Int: 5, } s, err := structs.New(&t) if err != nil { fmt.Printf("New[Error]: %v.\n", err) return } fmt.Printf("Name : %v.\n", s.Name()) fmt.Printf("Value of 1st field : %v.\n", s.Field(0).Value()) fmt.Printf("Value of Uint : %v.\n", s.Field("Uint").Value()) fmt.Printf("Value of Int : %v.\n", s.Field("Int").Value()) fmt.Printf("Sprint: %s.\n", s.Sprint()) err = s.Field("Uint").Set(uint(654321)) if err != nil { fmt.Printf("Set[Error]: %v.\n", err) } err = s.Field("Int").Set(6) if err != nil { fmt.Printf("Set[Error]: %v.\n", err) } err = s.Field("Bool").Set(6) if err != nil { fmt.Printf("Set[Error]: %v.\n", err) } fmt.Printf("Value of String : %s.\n", s.Field("String").String()) // syntax for %s verb fmt.Printf("Value of Uint : %d.\n", s.Field("Uint").Uint()) // syntax for %d verb fmt.Printf("Value of Int : %d.\n", s.Field("Int").Int()) // syntax for %d verb fmt.Printf("Sprint: %s.\n", s.Sprint()) fmt.Printf("\nVerification :\n") fmt.Printf("t.String : %s.\n", t.String) fmt.Printf("t.Uint : %d.\n", t.Uint) fmt.Printf("t.Int : %d.\n", t.Int) }
Output: Name : T. Value of 1st field : Roninzo. Value of Uint : 123456. Value of Int : 5. Sprint: { "String": "Roninzo", "Uint": 123456, "Bool": true, "Int": 5 }. Set[Error]: wrong kind of value for field T.Bool. got: "int" want: "bool". Value of String : Roninzo. Value of Uint : 654321. Value of Int : 6. Sprint: { "String": "Roninzo", "Uint": 654321, "Bool": true, "Int": 6 }. Verification : t.String : Roninzo. t.Uint : 654321. t.Int : 6.
func (*StructValue) CanSet ¶
func (s *StructValue) CanSet() bool
CanSet reports whether the value of StructValue can be changed. A StructValue can be changed only if it is addressable and was not obtained by the use of unexported struct fields. If CanSet returns false, calling Set or any type-specific setter (e.g., SetBool, SetInt) will panic.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Program struct { Name string `json:"name,omitempty"` } type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` Program *Program `json:"program,omitempty"` } program := Program{ Name: "Apache", } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", Program: &program, } s1, _ := structs.New(&server) s2, _ := structs.New(server) fmt.Printf("CanSet: %v\n", s1.CanSet()) fmt.Printf("CanSet: %v\n", s2.CanSet()) }
Output: CanSet: true CanSet: false
func (*StructValue) Contains ¶
func (s *StructValue) Contains(dest interface{}) int
Contains returns index field of struct inside interface dest. Unexported struct fields will be neglected.
func (*StructValue) Debug ¶
func (s *StructValue) Debug() string
Debug dumps the StructValue object itself as json string.
func (*StructValue) Defaults ¶ added in v1.0.5
func (s *StructValue) Defaults() error
Defaults initializes struct from inline default struct tags. Unsettable and zero-value fields will be neglected.
func (*StructValue) Diff ¶ added in v1.0.3
func (s *StructValue) Diff(c *StructValue) (map[string]interface{}, error)
Diff returns the differences in field values between two StructValue.
Example ¶
package main import ( "fmt" "sort" "time" "github.com/pkg/errors" "github.com/roninzo/pointers" "github.com/roninzo/structs" ) func main() { s1, err := structs.New(&structV) if err != nil { fmt.Printf("New[Error]: %v.\n", err) return } s2, err := structs.New(&structX) if err != nil { fmt.Printf("New[Error]: %v.\n", err) return } diffs, err := s2.Diff(s1) if err != nil { fmt.Printf("Diff[Error]: %v.\n", err) return } keys := make([]string, len(diffs)) i := 0 for key := range diffs { keys[i] = key i++ } sort.Strings(keys) for _, key := range keys { fmt.Printf("Diff[%s]: %+v.\n", key, structs.SprintCompact(diffs[key])) } } type structTest struct { String string `json:"string,omitempty"` Bool bool `json:"bool,omitempty"` Int int `json:"int,omitempty"` Uint uint `json:"uint,omitempty"` Float float32 `json:"float,omitempty"` Complex complex128 `json:"complex,omitempty"` Bytes []byte `json:"bytes,omitempty"` Interface interface{} `json:"interface,omitempty"` Error error `json:"error,omitempty"` Time time.Time `json:"time,omitempty"` Duration time.Duration `json:"duration,omitempty"` NestedStruct structNested `json:"nested_struct,omitempty"` PtrString *string `json:"pointer_string,omitempty"` PtrBool *bool `json:"pointer_bool,omitempty"` PtrInt *int `json:"pointer_int,omitempty"` PtrUint *uint `json:"pointer_uint,omitempty"` PtrFloat *float32 `json:"pointer_float,omitempty"` PtrComplex *complex128 `json:"pointer_complex,omitempty"` PtrError *error `json:"pointer_error,omitempty"` PtrTime *time.Time `json:"pointer_time,omitempty"` PtrDuration *time.Duration `json:"pointer_duration,omitempty"` PtrNestedStruct *structNested `json:"pointer_nested_struct,omitempty"` MapString map[string]string `json:"map_string,omitempty"` MapBool map[string]bool `json:"map_bool,omitempty"` MapInt map[string]int `json:"mapint,omitempty"` MapUint map[string]uint `json:"map_uint,omitempty"` MapFloat map[string]float32 `json:"map_float,omitempty"` MapComplex map[string]complex128 `json:"map_complex,omitempty"` MapInterface map[string]interface{} `json:"map_interface,omitempty"` SliceString []string `json:"slice_string,omitempty"` SliceBool []bool `json:"slice_bool,omitempty"` SliceInt []int `json:"slice_int,omitempty"` SliceUint []uint `json:"slice_uint,omitempty"` SliceFloat []float32 `json:"slice_float,omitempty"` SliceComplex []complex128 `json:"slice_complex,omitempty"` SliceInterface []interface{} `json:"slice_interface,omitempty"` SlicePtrString []*string `json:"slice_pointer_string,omitempty"` SlicePtrBool []*bool `json:"slice_pointer_bool,omitempty"` SlicePtrInt []*int `json:"slice_pointer_int,omitempty"` SlicePtrUint []*uint `json:"slice_pointer_uint,omitempty"` SlicePtrFloat []*float32 `json:"slice_pointer_float,omitempty"` SlicePtrComplex []*complex128 `json:"slice_pointer_complex,omitempty"` Hidden string `json:"-"` unexported bool } type structNested struct { Uint uint `json:"uint,omitempty"` String string `json:"string,omitempty"` } var structV structTest = structTest{ String: "Roninzo", Bool: true, Int: 8, Uint: uint(123456), Float: 1922.50, Complex: complex(22, 50), Bytes: []byte("Hello world"), Interface: "anything", Error: errors.New("rows not found"), Time: time.Date(2021, time.August, 3, 16, 44, 46, 0, time.UTC), Duration: 5 * time.Second, NestedStruct: structNested{Uint: 122334, String: "Apache"}, PtrString: pointers.String("Roninzo"), PtrBool: pointers.Bool(true), PtrInt: pointers.Int(8), PtrUint: pointers.Uint(uint(123456)), PtrFloat: pointers.Float32(1922.50), PtrComplex: pointers.Complex128(complex(22, 50)), PtrError: pointers.Error(errors.New("rows not found")), PtrTime: pointers.Time(time.Date(2021, time.August, 3, 16, 44, 46, 0, time.UTC)), PtrDuration: pointers.Duration(5 * time.Second), PtrNestedStruct: &structNested{Uint: 122334, String: "Apache"}, MapString: map[string]string{"A": "one", "B": "two", "C": "three"}, MapBool: map[string]bool{"A": true, "B": false}, MapInt: map[string]int{"A": 1, "B": 2, "C": 3}, MapUint: map[string]uint{"A": uint(1), "B": uint(2), "C": uint(3)}, MapFloat: map[string]float32{"A": 1.1, "B": 1.2, "C": 1.3}, MapComplex: map[string]complex128{"A": complex(1, 1), "B": complex(1, 2), "C": complex(1, 3)}, MapInterface: map[string]interface{}{"A": 1, "B": "two", "C": 3.0}, SliceString: []string{"one", "two", "three"}, SliceBool: []bool{true, false}, SliceInt: []int{1, 2, 3}, SliceUint: []uint{uint(1), uint(2), uint(3)}, SliceFloat: []float32{1.1, 1.2, 1.3}, SliceComplex: []complex128{complex(1, 1), complex(1, 2), complex(1, 3)}, SliceInterface: []interface{}{1, "two", 3.0}, SlicePtrString: []*string{pointers.String("one"), pointers.String("two"), pointers.String("three")}, SlicePtrBool: []*bool{pointers.Bool(true), pointers.Bool(false)}, SlicePtrInt: []*int{pointers.Int(1), pointers.Int(2), pointers.Int(3)}, SlicePtrUint: []*uint{pointers.Uint(uint(1)), pointers.Uint(uint(2)), pointers.Uint(uint(3))}, SlicePtrFloat: []*float32{pointers.Float32(1.1), pointers.Float32(1.2), pointers.Float32(1.3)}, SlicePtrComplex: []*complex128{pointers.Complex128(complex(1, 1)), pointers.Complex128(complex(1, 2)), pointers.Complex128(complex(1, 3))}, Hidden: "abcdefg", unexported: true, } var structX structTest = structTest{ String: "ozninoR", Bool: false, Int: 3, Uint: uint(654321), Float: 7622.50, Complex: complex(-67, -42), Bytes: []byte("Bye bye world"), Interface: 3.99, Error: errors.New("not compliant"), Time: time.Date(2021, time.August, 31, 14, 11, 11, 0, time.UTC), Duration: 30 * time.Second, NestedStruct: structNested{Uint: 443211, String: "Microsoft IIS"}, PtrString: pointers.String("ozninoR"), PtrBool: pointers.Bool(false), PtrInt: pointers.Int(3), PtrUint: pointers.Uint(uint(654321)), PtrFloat: pointers.Float32(7622.50), PtrComplex: pointers.Complex128(complex(-67, -42)), PtrError: pointers.Error(errors.New("not compliant")), PtrTime: pointers.Time(time.Date(2021, time.August, 31, 14, 11, 11, 0, time.UTC)), PtrDuration: pointers.Duration(30 * time.Second), PtrNestedStruct: &structNested{Uint: 443211, String: "Microsoft IIS"}, MapString: map[string]string{"D": "four", "E": "five", "F": "six"}, MapBool: map[string]bool{"D": false, "E": true}, MapInt: map[string]int{"D": 4, "E": 5, "F": 6}, MapUint: map[string]uint{"D": uint(4), "E": uint(5), "F": uint(6)}, MapFloat: map[string]float32{"D": 1.4, "E": 1.5, "F": 1.6}, MapComplex: map[string]complex128{"D": complex(1, 4), "E": complex(1, 5), "F": complex(1, 6)}, MapInterface: map[string]interface{}{"D": 4, "E": "five", "F": 6.0}, SliceString: []string{"four", "five", "six"}, SliceBool: []bool{false, true}, SliceInt: []int{4, 5, 6}, SliceUint: []uint{uint(4), uint(5), uint(6)}, SliceFloat: []float32{1.4, 1.5, 1.6}, SliceComplex: []complex128{complex(1, 4), complex(1, 5), complex(1, 6)}, SliceInterface: []interface{}{4, "five", 6.0}, SlicePtrString: []*string{pointers.String("four"), pointers.String("five"), pointers.String("six")}, SlicePtrBool: []*bool{pointers.Bool(false), pointers.Bool(true)}, SlicePtrInt: []*int{pointers.Int(4), pointers.Int(5), pointers.Int(6)}, SlicePtrUint: []*uint{pointers.Uint(uint(4)), pointers.Uint(uint(5)), pointers.Uint(uint(6))}, SlicePtrFloat: []*float32{pointers.Float32(1.4), pointers.Float32(1.5), pointers.Float32(1.6)}, SlicePtrComplex: []*complex128{pointers.Complex128(complex(1, 4)), pointers.Complex128(complex(1, 5)), pointers.Complex128(complex(1, 6))}, Hidden: "gfedcba", unexported: false, }
Output: Diff[bool]: false. Diff[bytes]: "QnllIGJ5ZSB3b3JsZA==". Diff[complex]: json: unsupported type: complex128. Diff[duration]: 30000000000. Diff[error]: "not compliant". Diff[float]: 7622.5. Diff[hidden]: "gfedcba". Diff[int]: 3. Diff[interface]: 3.99. Diff[map_bool]: {"D":false,"E":true}. Diff[map_complex]: json: unsupported type: complex128. Diff[map_float]: {"D":1.4,"E":1.5,"F":1.6}. Diff[map_interface]: {"D":4,"E":"five","F":6}. Diff[map_string]: {"D":"four","E":"five","F":"six"}. Diff[map_uint]: {"D":4,"E":5,"F":6}. Diff[mapint]: {"D":4,"E":5,"F":6}. Diff[nested_struct]: {"uint":443211,"string":"Microsoft IIS"}. Diff[pointer_bool]: false. Diff[pointer_complex]: json: unsupported type: complex128. Diff[pointer_duration]: 30000000000. Diff[pointer_error]: "not compliant". Diff[pointer_float]: 7622.5. Diff[pointer_int]: 3. Diff[pointer_nested_struct]: {"uint":443211,"string":"Microsoft IIS"}. Diff[pointer_string]: "ozninoR". Diff[pointer_time]: "2021-08-31T14:11:11Z". Diff[pointer_uint]: 654321. Diff[slice_bool]: [false,true]. Diff[slice_complex]: json: unsupported type: complex128. Diff[slice_float]: [1.4,1.5,1.6]. Diff[slice_int]: [4,5,6]. Diff[slice_interface]: [4,"five",6]. Diff[slice_pointer_bool]: [false,true]. Diff[slice_pointer_complex]: json: unsupported type: complex128. Diff[slice_pointer_float]: [1.4,1.5,1.6]. Diff[slice_pointer_int]: [4,5,6]. Diff[slice_pointer_string]: ["four","five","six"]. Diff[slice_pointer_uint]: [4,5,6]. Diff[slice_string]: ["four","five","six"]. Diff[slice_uint]: [4,5,6]. Diff[string]: "ozninoR". Diff[time]: "2021-08-31T14:11:11Z". Diff[uint]: 654321.
func (*StructValue) Err ¶
func (s *StructValue) Err() (err error)
Err gets error from StructValue, then resets internal error.
func (*StructValue) Field ¶
func (s *StructValue) Field(dest interface{}) *StructField
Field returns nil or one of the fields of the struct that matches argument dest. Its argument dest can be the name or the index of the field. Field(nil) returns nil and adds an error to StructValue.
NOTE: Field is an alias to either the getFieldByName or the getFieldByIndex method.
TODO: getFieldByIndex ability to access nested field names using []int as index.
e.g.: [1, 3, 1] <=> v.Field(1).Field(3).Field(1)
TODO: getFieldByName ability to parse nested field names inside n.
e.g.: "Struct.Nested.String" <=> v.FieldByName("Struct").FieldByName("Nested").FieldByName("String")
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } f1 := s.Field(0) f2 := s.Field("Enabled") fmt.Printf("Field.Name: %v\n", f1.Name()) fmt.Printf("Field.Value: %v\n", f1.Value()) fmt.Printf("Field.Name: %v\n", f2.Name()) fmt.Printf("Field.Value: %v\n", f2.Value()) }
Output: Field.Name: Name Field.Value: Roninzo Field.Name: Enabled Field.Value: true
func (*StructValue) Fields ¶
func (s *StructValue) Fields() StructFields
Fields returns all the fields of the struct in a slice. This method is not recursive, which means that nested structs must be dealt with explicitly.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` unexported bool } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", unexported: true, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } fmt.Printf("NumField: %d\n", s.NumField()) fields := s.Fields() if err != nil { fmt.Printf("Error: %v\n", err) } fmt.Printf("Fields.Names: %v\n", fields.Names()) }
Output: NumField: 6 Fields.Names: [Name ID Enabled Count Password unexported]
func (*StructValue) FindStruct ¶
func (s *StructValue) FindStruct(name string) *StructValue
FindStruct recursively finds and returns the StructValue object matching provided name, i.e.: the name of struct desired.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Program struct { Name string `json:"name,omitempty"` } type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` Program *Program `json:"program,omitempty"` } program := Program{ Name: "Apache", } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", Program: &program, } s1, _ := structs.New(&server) s2 := s1.FindStruct("Program") fmt.Printf("Program.Name: %v\n", s2.Name()) fmt.Printf("Program.Value: %v\n", s2.Value()) }
Output: Program.Name: Program Program.Value: {Apache}
func (*StructValue) Forward ¶
func (s *StructValue) Forward(c *StructValue) error
Forward loops through destination fields of struct s and set their values to the corresponding fields from c. Zero-value fields from c will be neglected. Unsettable struct fields will be neglected.
func (*StructValue) FullName ¶ added in v1.0.5
func (s *StructValue) FullName() string
FullName returns the same as the Name method, unless StructValue is a nested struct. When dealing with a nested struct, parent struct names are looked up and concatenated to the response recursively all the way to the top level struct.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Program struct { Name string `json:"name,omitempty"` } type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` Program *Program `json:"program,omitempty"` } program := Program{ Name: "Apache", } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", Program: &program, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } p := s.FindStruct("Program") fmt.Printf("FullName: %v\n", s.FullName()) fmt.Printf("FullName: %v\n", p.FullName()) }
Output: FullName: Server FullName: Server.Program
func (*StructValue) HasField ¶
func (s *StructValue) HasField(dest interface{}, arg interface{}) (bool, error)
HasField returns true if struct dest has a field called the same as argument name.
func (*StructValue) HasNested ¶
func (s *StructValue) HasNested() bool
HasNested returns true if struct has one or more nested struct within the root struct. HasNested returns false if none of the fields is sub-struct.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Program struct { Name string `json:"name,omitempty"` } type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` Program *Program `json:"program,omitempty"` } program := Program{ Name: "Apache", } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", Program: &program, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } p, err := structs.New(&program) if p.Error != nil { fmt.Printf("Error: %s\n", p.Error) } fmt.Printf("Server.HasNested: %v\n", s.HasNested()) fmt.Printf("Program.HasNested: %v\n", p.HasNested()) }
Output: Server.HasNested: true Program.HasNested: false
func (*StructValue) HasZero ¶
func (s *StructValue) HasZero() bool
HasZero returns true if one or more struct fields are of zero value. Unexported struct fields will be neglected.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` } server := Server{ Name: "Roninzo", ID: 0, // zero-value Enabled: true, Count: 5, Password: "abcdefg", } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } fmt.Printf("HasZero: %v\n", s.HasZero()) server = Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 5, Password: "abcdefg", } s, err = structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } fmt.Printf("HasZero: %v\n", s.HasZero()) }
Output: HasZero: true HasZero: false
func (*StructValue) Import ¶
func (s *StructValue) Import(c *StructValue) error
Import loops through destination fields of struct s and set their values to the corresponding fields from c. Usually, s is a trim-down version of c. Unsettable struct fields will be neglected.
func (*StructValue) IndirectValues ¶ added in v1.0.5
func (s *StructValue) IndirectValues() (values []reflect.Value)
IndirectValues returns the values of the struct as a slice of reflect Values recursively.
Example ¶
package main import ( "fmt" "github.com/roninzo/pointers" "github.com/roninzo/structs" ) func main() { type Program struct { Name *string `json:"name,omitempty"` } type Server struct { Name *string `json:"name,omitempty"` ID *uint `json:"id,omitempty"` Enabled *bool `json:"enabled,omitempty"` Count *int `json:"count,omitempty"` Program *Program `json:"program,omitempty"` Password *string `json:"-"` unexported *bool } pointers.NullifyZeroValues = false program := Program{ Name: pointers.String("Apache"), } server := Server{ Name: pointers.String("Roninzo"), ID: pointers.Uint(123456), Enabled: pointers.Bool(true), Count: pointers.Int(0), Program: &program, Password: pointers.String("abcdefg"), unexported: pointers.Bool(true), } pointers.NullifyZeroValues = true s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v.\n", err) } // json struct tag omits Password and Count for i, value := range s.IndirectValues() { fmt.Printf("IndirectValues[%d]: %v.\n", i, value) } }
Output: IndirectValues[0]: Roninzo. IndirectValues[1]: 123456. IndirectValues[2]: true. IndirectValues[3]: 0. IndirectValues[4]: Apache. IndirectValues[5]: abcdefg. IndirectValues[6]: true.
func (*StructValue) IsNested ¶
func (s *StructValue) IsNested() bool
IsNested returns true if struct is a nested struct within the root struct. IsNested returns false if StructValue is the top level struct.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Program struct { Name string `json:"name,omitempty"` } type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` Program *Program `json:"program,omitempty"` } program := Program{ Name: "Apache", } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", Program: &program, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } p := s.FindStruct("Program") fmt.Printf("Server.IsNested: %v\n", s.IsNested()) fmt.Printf("Program.IsNested: %v\n", p.IsNested()) }
Output: Server.IsNested: false Program.IsNested: true
func (*StructValue) IsValid ¶
func (s *StructValue) IsValid() bool
IsValid returns true if the struct was found. It is so when StructValue represents a reflect value.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string ID uint Enabled bool Count int32 } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 5, } s, err := structs.New(nil) if err != nil { fmt.Printf("Error: %v\n", err) } else { fmt.Printf("IsValid: %v\n", s.IsValid()) } s, err = structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } else { fmt.Printf("IsValid: %v\n", s.IsValid()) } }
Output: Error: invalid concrete value; want: "struct" or "ptr" or "slice", got: <nil> IsValid: true
func (*StructValue) IsZero ¶
func (s *StructValue) IsZero() bool
IsZero returns true if all struct fields are of zero value. Unexported struct fields will be neglected.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } fmt.Printf("IsZero: %v\n", s.IsZero()) server = Server{ Name: "", ID: 0, Enabled: false, Count: 0, Password: "", } s, err = structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } fmt.Printf("IsZero: %v\n", s.IsZero()) }
Output: IsZero: false IsZero: true
func (*StructValue) Kind ¶
func (s *StructValue) Kind() reflect.Kind
Kind returns the struct reflect kind, or the last kind identified when the struct could not be found.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string ID uint Enabled bool Count int32 } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 5, } s, err := structs.New(nil) if err != nil { fmt.Printf("Error: %v\n", err) } if s != nil { fmt.Printf("Kind: %v\n", s.Kind()) } s, err = structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } fmt.Printf("Kind: %v\n", s.Kind()) }
Output: Error: invalid concrete value; want: "struct" or "ptr" or "slice", got: <nil> Kind: struct
func (*StructValue) MapFunc ¶
func (s *StructValue) MapFunc(handler func(reflect.Value) error) (*StructValue, error)
MapFunc maps struct with func handler.
func (*StructValue) Multiple ¶
func (s *StructValue) Multiple() bool
Multiple reports whether the value of StructValue is a slice of structs. If Multiple returns false, either the struct was not found or it was not part of a slice of them.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", } s1, _ := structs.New(&server) s2, _ := structs.New([]*Server{&server}) fmt.Printf("Multiple: %v\n", s1.Multiple()) fmt.Printf("Multiple: %v\n", s2.Multiple()) }
Output: Multiple: false Multiple: true
func (*StructValue) Name ¶
func (s *StructValue) Name() string
Name returns the name of the struct. When the struct was not found, it returns zero-value string.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string ID uint Enabled bool Count int32 } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 5, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } fmt.Printf("Name: %v\n", s.Name()) }
Output: Name: Server
func (*StructValue) NumField ¶
func (s *StructValue) NumField() int
NumField returns the number of fields in the struct. This method is not recursive, which means that nested structs must be dealt with explicitly.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } fmt.Printf("NumField: %v\n", s.NumField()) }
Output: NumField: 5
func (*StructValue) Path ¶
func (s *StructValue) Path() string
Path returns a comma separated string of reflect.Kind.String describing where the struct was found inside the interface input of the New method.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 5, Password: "abcdefg", } s1, _ := structs.New(server) s2, _ := structs.New(&server) s3, _ := structs.New([]Server{server}) s4, _ := structs.New(&[]Server{server}) s5, _ := structs.New([]*Server{&server}) fmt.Printf("Path: %v\n", s1.Path()) fmt.Printf("Path: %v\n", s2.Path()) fmt.Printf("Path: %v\n", s3.Path()) fmt.Printf("Path: %v\n", s4.Path()) fmt.Printf("Path: %v\n", s5.Path()) }
Output: Path: struct Path: ptr,struct Path: slice,struct Path: ptr,slice,struct Path: slice,ptr,struct
func (*StructValue) Rows ¶
func (s *StructValue) Rows() (*StructRows, error)
Rows returns an iterator, for a slice of structs. Rows returns nil if there was an error.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Count int32 `json:"count,omitempty"` } servers := []Server{ {Count: 5}, {Count: 6}, } s, err := structs.New(&servers) if err != nil { fmt.Printf("New: %v.\n", err) } rows, err := s.Rows() if err != nil { fmt.Printf("Rows[Error]: %v.\n", err) } defer rows.Close() cols, err := rows.Columns() if err != nil { fmt.Printf("Columns[Error]: %v.\n", err) } fmt.Printf("Row: %s.\n", s.Sprint()) fmt.Printf("StructValue: %s.\n", s.Debug()) fmt.Printf("Len: %d.\n", rows.Len()) fmt.Printf("MaxRow: %d.\n", rows.MaxRow()) fmt.Printf("Columns: %v.\n", cols) for rows.Next() { f := rows.Field("Count") fmt.Printf("[%d] %s: %d.\n", rows.Index(), f.Name(), f.Int()) c := f.Int() err := f.Set(c * 10) if err != nil { fmt.Printf("Set[Error]: %v.\n", err) } fmt.Printf("[%d] %s: %d.\n", rows.Index(), f.Name(), f.Int()) } if err := rows.Err(); err != nil { fmt.Printf("Err[Error]: %v.\n", err) } fmt.Println("Verification:") fmt.Printf("servers[0].Count: %d.\n", servers[0].Count) fmt.Printf("servers[1].Count: %d.\n", servers[1].Count) }
Output: Row: { "count": 5 }. StructValue: { "value": { "count": 5 }, "rows": [ { "count": 5 }, { "count": 6 } ], "max_row": 2, "kinds": "ptr,slice,struct", "fields": { "0": "Count" }, "parent": "", "error": null }. Len: 2. MaxRow: 1. Columns: [Count]. [0] Count: 5. [0] Count: 50. [1] Count: 6. [1] Count: 60. Verification: servers[0].Count: 50. servers[1].Count: 60.
Example (Empty) ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Count int32 `json:"count,omitempty"` } servers := []Server{} s, err := structs.New(&servers) if err != nil { fmt.Printf("New[Error]: %v.\n", err) } rows, err := s.Rows() if err != nil { fmt.Printf("Rows[Error]: %v.\n", err) } if rows != nil { fmt.Printf("Rows: %v.\n", rows) } }
Output: Rows[Error]: struct rows not found.
Example (NotMultiple) ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Count int32 `json:"count,omitempty"` } server := Server{ Count: 5, } s, err := structs.New(&server) if err != nil { fmt.Printf("New[Error]: %v.\n", err) } rows, err := s.Rows() if err != nil { fmt.Printf("Rows[Error]: %v.\n", err) } if rows != nil { fmt.Printf("Rows: %v.\n", rows) } }
Output: Rows[Error]: structs not found.
func (*StructValue) Sprint ¶ added in v1.0.1
func (s *StructValue) Sprint() string
Sprint returns struct as a string, similar to the Values method, but in a json indented format. When the struct was not found, it returns zero-value string. Unexported struct fields will be neglected.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Program struct { Name string `json:"name,omitempty"` } type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` Program Program `json:"program,omitempty"` } program := Program{ Name: "Apache", } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", Program: program, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } // json struct tag omits Password and Count fmt.Printf("Sprint: %s\n", s.Sprint()) }
Output: Sprint: { "name": "Roninzo", "id": 123456, "enabled": true, "program": { "name": "Apache" } }
func (*StructValue) Type ¶
func (s *StructValue) Type() reflect.Type
Type returns the type struct name, including the name of package, such as "structs.T".
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string ID uint Enabled bool Count int32 } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 5, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } fmt.Printf("Type: %v\n", s.Type()) }
Output: Type: structs_test.Server
func (*StructValue) Value ¶
func (s *StructValue) Value() (v reflect.Value)
Value returns the reflect value of the struct when the struct was found, else it returns zero-value reflect value.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Server struct { Name string ID uint Enabled bool Count int32 } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 5, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } fmt.Printf("Value: %v\n", s.Value()) }
Output: Value: {Roninzo 123456 true 5}
func (*StructValue) Values ¶
func (s *StructValue) Values() (values []reflect.Value)
Values returns the values of the struct as a slice of interfaces recursively. Unexported struct fields will be neglected.
Example ¶
package main import ( "fmt" "github.com/roninzo/structs" ) func main() { type Program struct { Name string `json:"name,omitempty"` } type Server struct { Name string `json:"name,omitempty"` ID uint `json:"id,omitempty"` Enabled bool `json:"enabled,omitempty"` Count int32 `json:"count,omitempty"` Password string `json:"-"` Program Program `json:"program,omitempty"` unexported bool } program := Program{ Name: "Apache", } server := Server{ Name: "Roninzo", ID: 123456, Enabled: true, Count: 0, Password: "abcdefg", Program: program, } s, err := structs.New(&server) if err != nil { fmt.Printf("Error: %v\n", err) } // json struct tag omits Password and Count for i, value := range s.Values() { fmt.Printf("Values[%d]: %v\n", i, value) } }
Output: Values[0]: Roninzo Values[1]: 123456 Values[2]: true Values[3]: 0 Values[4]: abcdefg Values[5]: Apache
Notes ¶
Bugs ¶
Sprint uses json marshaling which does not support complex types (complex64/complex128).
the MapFunc method argument dest is also changed. should that be the case?
the New method behaves unexpectidely when passing in an empty slice of pointers to structs.
StructValue.New
StructValue.findStruct(v, t) => IndirectStruct StructValue.getElem(v, t) => IndirectValueAndType utils.StructValueElem(v, t)
TODEL: New Load parent StructValue, if any.
TODEL: findStruct findStruct finds where the struct is inside the reflect value and type. By being chainable, findStruct uses withStruct to finalize successful completion and exit the switch case below, all in a one-liner, otherwise it returns the StructValue explictly at the end. See the Support paragraph in the documentation for more details.
TODEL: withStruct withStruct returns StructValue object after setting reflect.Value of struct found. By being chainable, withStruct can finalize StructValue and return it at the same time.
TODEL: getElem getElem returns the element or the first element of the reflection pointer value and type. It saves an errors inside StructValue if the type's Kind is not Array, Ptr, or Slice.
TODEL: appendKind appendKind appends reflect type t to the slice of kinds in StructValue. The first, it initialized kinds as a the slice of kinds.
TODEL: utils.StructValueElem StructValueElem follows the pointer v and returns the element it points to, for borth reflect value and reflect type, as well as nil error. If v is not a pointer or not a supported pointer, it returns zero-value reflect value and reflect type as well as an error.
MIGRATE: utils.CanStruct CanStruct returns true if reflect value represents a nested struct, else returns false.