refutil

package module
v0.0.0-...-b444d14 Latest Latest
Warning

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

Go to latest
Published: Feb 15, 2022 License: MIT Imports: 4 Imported by: 0

README

PkgGoDev CI

Reflect Util

reflect functionality and sugar we often use in our projects. Who knows maybe you will find it useful as well.

Features:

  • Ability to compare (underlying) values
  • Searching for specific values in map, slice, array or structs
  • Various check functions
  • Easier work with pointers
  • Sugar to not repeat functionality done with reflect
  • Iterator implementation

Package follows same principles of handling errors as reflect itself. Instead of returning errors when something goes wrong it panics. But only when supplied arguments are invalid. You also have ability to use Can* methods like CanIndex and others to prevent panicking.

Install

Installation is available with go get command

go get -u  gomodules.xyz/refutil

Few examples from refutil package

Equal(source, compare interface{})

this method is intended to compare 2 interfaces if they are same or not. First implementation stolen from Testify Assert. Difference between refutil.DeepEqual and refutil.Equal is that refutil.Equal dont care about underlying type as long as types are convertible.

refutil.Equal(uint(1), 1) // true

of course this is possible with any type, not just numeric ones.

IsZero(a interface{})

Will check if underlying value is Zero. For any kind of type. Check zero_test.go to see all cases.

var header []string
refutil.IsZero(uint(2)) // false
refutil.IsZero(uint(0)) // true
refutil.IsZero(nil) // true
refutil.IsZero((*time.Time)(nil)) // true
refutil.IsZero(header) // true
refutil.IsZero([]string{}) // true
refutil.IsZero([]string{"1"}) // false
// and os on
IsNil(a interface {})

returns if object is nil or not. Look at example why you want to use it.

// Your custom error
type MyOwnError struct {}
func(err *MyOwnError) Error() string {return ""}

// Create new error of error interface
err := errors.New("ok")
err = (*MyOwnError)(nil)
// note err is still error interface
err == nil // false
refutil.IsNil(err) // true
Indirect(a interface {})

Will get value of interface{} if interface{} is pointer to something.

type K struct{}
k := K{}
refutil.Indirect(&k) == refutil.Indirect(k) // true
refutil.Indirect(nil) == refutil.Indirect((*K)(nil)) // true
Index(source, element interface{})

Index will return index of element in array or slice. It uses Equal / DeepEqual. Returns index if not found return -1.

Similar methods IndexSame

refutil.Index([]uint{1,2,3}, 2) // 1
refutil.IndexSame([]uint{1,2,3}, 2) // -1
refutil.IndexSame([]uint{1,2,3}, uint(2)) // 1
refutil.Index(struct{}{}, 2) // panics!
Contains(a, b interface{})

Similar to Index except it return boolean and can work with map, array, slice or struct.

Similar methods ContainsValue, ContainsSameValue, ContainsKey, ContainsSameKey

refutil.Contains([]uint{1,2,3}, 2) // true
refutil.ContainsSame([]uint{1,2,3}, uint(2)) // true
refutil.Contains(map[string]string{"test": "yes!"}, "yes!") // true
refutil.Contains(struct{}{}, 2) // false
Iteration

You have ability to implement your own iteration

data := NewData([]uint{1,2,3,4})
data.Iterate(func (iterator *Iterator) {
    // return key value pair to of current iteration
    // key is key of map, struct or in case of slice its index
    // value is value for specific key
    kv := iterator.Current()
    // kv.Key.String() == "0"
    // kv.Value.String() == "1"
    // ...
    // stops iteration
    iterator.Stop()
    iterator.HasNext()
    iterator.CanNext()
    // other methods available
})

Package unsafe

Package unsafe provide simple functionality to bypass runtime check for private fields. It will get raw pointer so you can access anything you want. Very useful for debugging. But with this great power comes great responsibility. It is called unsafe for purpose.

Originally invented in go-spew.

unsafe.ReflectValue
type K struct {
    a int
}
v := unsafe.ReflectValue(reflect.ValueOf(&K))
// v is now reflect unsafe value

Credit

  • Richard Hutta
  • Mat Ryer
  • Tyler Bunnell
  • Fatih Arslan

Thank you guys for your great work.

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrArgumentNotIndexable = errors.New("argument can't be used to search index")

ErrArgumentNotIndexable is telling you that argument supplied to function is not a searchable for specific index

Functions

func CanIndirect

func CanIndirect(v interface{}) bool

CanIndirect will determine if value can be dereferenced refer to https://golang.org/pkg/reflect/#Value.Elem

func CanIndirectType

func CanIndirectType(t reflect.Type) bool

CanIndirectType will determine if type can be dereferenced refer to https://golang.org/pkg/reflect/#Type method Elem()

func CanIndirectValue

func CanIndirectValue(v reflect.Value) bool

CanIndirectValue will determine if value can be dereferenced refer to https://golang.org/pkg/reflect/#Value.Elem

func CanLen

func CanLen(x interface{}) bool

CanLen tells you if possible to search for len of given object. https://golang.org/pkg/reflect/#Value.Len

func Contains

func Contains(source interface{}, element interface{}) bool

Contains will search for specific value in list and return bool if found. It panics if list is not searchable

func ContainsKey

func ContainsKey(source interface{}, element interface{}) bool

ContainsKey will search for specific key in list and return bool if found. It panics if list is not searchable

func ContainsSameKey

func ContainsSameKey(source interface{}, element interface{}) bool

ContainsSameKey will search for specific key in list and return bool if found. It panics if list is not searchable. Unlike ContainsKey compared keys needs to be deep equal

func ContainsSameValue

func ContainsSameValue(source interface{}, element interface{}) bool

ContainsSameValue will search for specific value in list and return bool if found. It panics if list is not searchable. Unlike ContainsValue compared keys needs to be deep equal

func ContainsValue

func ContainsValue(source interface{}, element interface{}) bool

ContainsValue will search for specific value in list and return bool if found. it panics if list is not searchable

func DeepEqual

func DeepEqual(expected, actual interface{}) bool

DeepEqual determines if two Objects are considered equal. This is what reflect does, except this method add nil check for speed improvement

Example
fmt.Printf("%v\n", DeepEqual(uint(0), 0))
fmt.Printf("%v\n", DeepEqual(0, 0))
Output:

false
true

func Equal

func Equal(expected, actual interface{}) bool

Equal gets whether two Objects are equal. It don't cares about underlying type. If first argument is compliant with `Equalizer` interface then it will use `Equal(interface) bool` on type to compare. Otherwise it try to compare using `DeepEqual` and same types.

Example
fmt.Printf("%v\n", Equal(uint(0), 0))
// implements `Equal(v interface{}) bool`
// checkout type `YourStruct`
a := &YourStruct{A: "same"}
b := &DiffStruct{A: "same"}
fmt.Printf("%v\n", Equal(a, b))
Output:

true
true

func Index

func Index(list interface{}, element interface{}) int

Index will search for specific element in list and return index. If not found returns -1. If list is not list it will panic

func IndexSame

func IndexSame(list interface{}, element interface{}) int

IndexSame will search for specific element in list and return index. If not found returns -1. If list is not list it will panic. But unlike Index it will compare values so they must be deep equal.

func Indirect

func Indirect(v interface{}) interface{}

Indirect will return actual value insted of pointer if values is passed value is returned

func IsKind

func IsKind(t Kinder, kind reflect.Kind) bool

IsKind return true if type or value is specific kind

func IsNil

func IsNil(object interface{}) bool

IsNil checks if a specified object is nil or not also check underlying type if its nil or not

func IsZero

func IsZero(v interface{}) bool

IsZero return true if underlying type is equal to its zero value

func KindOneOf

func KindOneOf(t Kinder, kinds ...reflect.Kind) bool

KindOneOf return true if type is one of the kind supplied

func Len

func Len(x interface{}) (length int)

Len try to get length of object.

func PathTo

func PathTo(v interface{}) string

PathTo will return actual path to package where interface{} is defined.

func String

func String(v interface{}) string

String return string from value

Types

type Comparator

type Comparator func(interface{}, interface{}) bool

Comparator is used as abstraction for method like IsEqual which compare two values

type Data

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

Data is structure supporting this package but also have application outside. It helps to simplify working with reflect

func NewData

func NewData(v interface{}) Data

NewData creates new Data struct

func (Data) At

func (v Data) At(i int) (Value, Value)

At returns key value of given object if `Indexer` interface can be used

func (Data) CanIndirect

func (v Data) CanIndirect() bool

CanIndirect will determine if value can be dereferenced refer to https://golang.org/pkg/reflect/#Value.Elem

func (Data) CanInterface

func (v Data) CanInterface() bool

CanInterface returns whether value can interface

func (Data) CanLen

func (v Data) CanLen() bool

CanLen tells you if possible to search for len of given reflect.Value. https://golang.org/pkg/reflect/#Value.Len

func (Data) Compare

func (v Data) Compare(comparator Comparator, value Value) bool

Compare will use comparator to compare to another Value

func (Data) ContainsKey

func (v Data) ContainsKey(compare Comparator, element interface{}) bool

ContainsKey will search for specific key in list and return bool if found. It panics if list is not searchable

func (Data) ContainsValue

func (v Data) ContainsValue(compare Comparator, element interface{}) bool

ContainsValue will search for specific value in list and return bool if found. It panics if list is not searchable

func (Data) DeepEqual

func (v Data) DeepEqual(element interface{}) bool

DeepEqual determines if two Objects are considered equal. This is what reflect does, except this method add nil check for speed improvement

func (Data) Equal

func (v Data) Equal(element interface{}) bool

Equal gets whether two Objects are equal. It don't cares about underlying type. If first argument is compliant with `Equalizer` interface then it will use `Equal(interface) bool` on type to compare. Otherwise it try to compare using `DeepEqual` and same types.

func (Data) Indirect

func (v Data) Indirect() Data

Indirect will check if value can be dereferenced and dereference otherwise return value itself

func (Data) Interface

func (v Data) Interface() interface{}

Interface returns actual data originally inserted

func (Data) InterfaceOrNil

func (v Data) InterfaceOrNil() interface{}

InterfaceOrNil will either return interface or nil if interface cannot be obtained

func (Data) IsKind

func (v Data) IsKind(k reflect.Kind) bool

IsKind reports if data is specific kind

func (Data) IsNil

func (v Data) IsNil() bool

IsNil checks if a specified object is nil or not also check underlying type if its nil or not

func (Data) IsZero

func (v Data) IsZero() bool

IsZero return true if underlying type is equal to its zero value

func (Data) Iterate

func (v Data) Iterate(iterator IteratorFunc)

Iterate will iterate over struct map or slice providing key value of every element

func (Data) Iterator

func (v Data) Iterator() *Iterator

Iterator will create and return iterator struct

func (Data) KindOneOf

func (v Data) KindOneOf(k ...reflect.Kind) bool

KindOneOf reports if data is one if expected kinds

func (Data) Len

func (v Data) Len() (length int)

Len try to get length of object.

func (Data) PathTo

func (v Data) PathTo() string

PathTo will return actual path to package where interface{} is defined.

func (Data) Search

func (v Data) Search(iterator SearchFunc) *KeyValue

Search will iterate over struct map or slice providing key value of every element and return first result when iterator return true

func (Data) SearchIndex

func (v Data) SearchIndex(compare Comparator, element interface{}) int

SearchIndex will search for specific element in list and return index. If not found returns -1. it panics if list is not searchable

func (Data) SearchKey

func (v Data) SearchKey(compare Comparator, element interface{}) *KeyValue

SearchKey will search for specific key in struct slice or map

func (Data) SearchValue

func (v Data) SearchValue(compare Comparator, element interface{}) *KeyValue

SearchValue will search for specific value in struct slice or map

func (Data) String

func (v Data) String() string

String returns

func (Data) Type

func (v Data) Type() Type

Type will return reflect.TypeOf in wrapper Type and cache for later use

func (Data) Untyped

func (v Data) Untyped() Data

Untyped will return value it self if not nil. If nil rather then using value's nil it uses raw nil. This is useful in cases where you want instead of (*string)(nil) just nil

func (Data) Value

func (v Data) Value() Value

Value will return reflect.ValueOf in wrapper Value and cache for later use

type Equalizer

type Equalizer interface {
	Equal(v interface{}) bool
}

Equalizer is way how to check if object can compare it self to another object. Used only with `Equal` method

type Indexer

type Indexer interface {
	At(i int) (Value, Value)
	Keys() []Value
}

Indexer provides unified searching for key, value in map, struct or slice.

type Iterator

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

Iterator designed to manage iterations over indexer

func NewIterator

func NewIterator(v Value) *Iterator

NewIterator creates new iterator on value

func (*Iterator) CanNext

func (s *Iterator) CanNext() bool

CanNext consider if user wants to stop and if next element is available

func (*Iterator) Current

func (s *Iterator) Current() *KeyValue

Current return current key value

func (*Iterator) HasNext

func (s *Iterator) HasNext() bool

HasNext will tell you if next element is available

func (*Iterator) Index

func (s *Iterator) Index() int

Index return current iteration index

func (*Iterator) Len

func (s *Iterator) Len() int

Len will provide how many keys we are iterating over

func (*Iterator) Stop

func (s *Iterator) Stop()

Stop will stop iteration

type IteratorFunc

type IteratorFunc func(*Iterator)

IteratorFunc function iterates over Indexer providing key and value

type KeyValue

type KeyValue struct {
	Key   Value
	Value Value
}

KeyValue provides key value. Key just like value can be any interface. If slice key will be int wrapped in Value

func Search(source interface{}, iterator SearchFunc) *KeyValue

Search will iterate over struct map or slice providing key value of every element and return first result when iterator return true

func SearchKey

func SearchKey(source interface{}, element interface{}) *KeyValue

SearchKey will search for specific key in struct slice or map

func SearchSameKey

func SearchSameKey(source interface{}, element interface{}) *KeyValue

SearchSameKey will search for specific key in struct slice or map. Unlike SearchKey it the compared keys needs to be deep equal

func SearchSameValue

func SearchSameValue(source interface{}, element interface{}) *KeyValue

SearchSameValue will search for specific value in struct slice or map. Unlike SearchKey it compared keys needs to be deep equal

func SearchValue

func SearchValue(source interface{}, element interface{}) *KeyValue

SearchValue will search for specific value in struct slice or map

func (*KeyValue) Index

func (kv *KeyValue) Index() int

Index will return int as an index taken from key. This works only for slices

type Kinder

type Kinder interface {
	Kind() reflect.Kind
}

Kinder as interface for reflect.Value or reflect.Type Kind() method

type MapIndexer

type MapIndexer struct {
	Source Value
	// contains filtered or unexported fields
}

MapIndexer implements Indexer for maps

func NewMapIndexer

func NewMapIndexer(source Value) *MapIndexer

NewMapIndexer will create MapIndexer

func (*MapIndexer) At

func (v *MapIndexer) At(i int) (Value, Value)

At will return key value for index i

func (*MapIndexer) Keys

func (v *MapIndexer) Keys() []Value

Keys will return list of keys

type SearchFunc

type SearchFunc func(*KeyValue) bool

SearchFunc function iterates over Indexer providing key and value and return result if result of function is true

type SliceIndexer

type SliceIndexer struct {
	Source Value
	// contains filtered or unexported fields
}

SliceIndexer implements Indexer for slices or arrays

func NewSliceIndexer

func NewSliceIndexer(source Value) *SliceIndexer

NewSliceIndexer will create SliceIndexer

func (*SliceIndexer) At

func (v *SliceIndexer) At(i int) (Value, Value)

At will return key value for index i

func (*SliceIndexer) Keys

func (v *SliceIndexer) Keys() []Value

Keys will return list of keys

type StructIndexer

type StructIndexer struct {
	Source Value
	// contains filtered or unexported fields
}

StructIndexer implements Indexer for structs

func NewStructIndexer

func NewStructIndexer(source Value) *StructIndexer

NewStructIndexer will create StructIndexer

func (*StructIndexer) At

func (v *StructIndexer) At(i int) (Value, Value)

At will return key value for index i

func (*StructIndexer) Keys

func (v *StructIndexer) Keys() []Value

Keys will return list of keys

type Type

type Type struct {
	reflect.Type
}

Type is wrapper around reflect.Type

func IndirectType

func IndirectType(t reflect.Type) Type

IndirectType will check if type can be dereferenced and do so, otherwise return type itself panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice.

func IndirectTypeOf

func IndirectTypeOf(x interface{}) Type

IndirectTypeOf is shortcut to TypeOf().Elem(). only indirect if possible otherwise it returns current type

func NewType

func NewType(v interface{}) Type

NewType returns new type from interface{}

func (Type) CanIndirect

func (v Type) CanIndirect() bool

CanIndirect will determine if type can be dereferenced refer to https://golang.org/pkg/reflect/#Type method Elem()

func (Type) Indirect

func (v Type) Indirect() Type

Indirect will check if type can be dereferenced and do so, otherwise return type itself panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice.

func (Type) IsKind

func (t Type) IsKind(k reflect.Kind) bool

IsKind is sugar to simplify conditions

func (Type) IsNil

func (v Type) IsNil() bool

IsNil checks if type is nil

func (Type) KindOneOf

func (t Type) KindOneOf(k ...reflect.Kind) bool

KindOneOf is method to compare type against multiple reflect.Type with logical OR

func (Type) New

func (t Type) New() Value

New will create new pointer of this type

func (Type) NewSlice

func (t Type) NewSlice() Value

NewSlice will create empty slice (not slice header!)

func (Type) PathTo

func (v Type) PathTo() string

PathTo will return actual path to package where interface{} is defined.

func (Type) Zero

func (t Type) Zero() Value

Zero will return zero of type

type Value

type Value struct {
	reflect.Value
}

Value is wrapper around reflect.Value

func IndirectValue

func IndirectValue(v reflect.Value) Value

IndirectValue will check if value can be dereferenced and dereference otherwise return value itself

func IndirectValueOf

func IndirectValueOf(v interface{}) Value

IndirectValueOf is shortcut to ValueOf().Elem()

func NewValue

func NewValue(v interface{}) Value

NewValue will create new Value

func (Value) At

func (v Value) At(i int) (Value, Value)

At returns key value of given object if `Indexer` interface can be used

func (Value) CanIndex

func (v Value) CanIndex() bool

CanIndex tells you if you can get value from index. Checkout https://golang.org/pkg/reflect/#Value.Index

func (Value) CanIndirect

func (v Value) CanIndirect() bool

CanIndirect will determine if value can be dereferenced refer to https://golang.org/pkg/reflect/#Value.Elem

func (Value) CanInterface

func (v Value) CanInterface() bool

CanInterface returns whether value can interface

func (Value) CanLen

func (v Value) CanLen() bool

CanLen tells you if possible to search for len of given reflect.Value. https://golang.org/pkg/reflect/#Value.Len

func (Value) CanUseIndexer

func (v Value) CanUseIndexer() bool

CanUseIndexer return bool if Indexer Method can be used

func (Value) Compare

func (v Value) Compare(comparator Comparator, value Value) bool

Compare will use comparator to compare to another Value

func (Value) ContainsKey

func (v Value) ContainsKey(compare Comparator, element interface{}) bool

ContainsKey will search for specific key in list and return bool if found. It panics if list is not searchable

func (Value) ContainsValue

func (v Value) ContainsValue(compare Comparator, element interface{}) bool

ContainsValue will search for specific value in list and return bool if found. It panics if list is not searchable

func (Value) Index

func (v Value) Index(i int) Value

Index is just wrapper of regular index method. It will indirect value if is pointer

func (Value) Indexer

func (v Value) Indexer() Indexer

Indexer will return proper Indexer interface

func (Value) Indirect

func (v Value) Indirect() Value

Indirect will check if value can be dereferenced and dereference otherwise return value itself

func (Value) InterfaceOrNil

func (v Value) InterfaceOrNil() interface{}

InterfaceOrNil will either return interface or nil if interface cannot be obtained

func (Value) IsKind

func (t Value) IsKind(k reflect.Kind) bool

IsKind is sugar to simplify conditions

func (Value) IsNil

func (v Value) IsNil() bool

IsNil will check if you can ask reflect for IsNil and if its pointer it will recursively check until its resolved

func (Value) IsZero

func (v Value) IsZero() bool

IsZero return true if underlying type is equal to its zero value

func (Value) Iterate

func (v Value) Iterate(iterator IteratorFunc)

Iterate will iterate over struct map or slice providing iterator object

func (Value) Iterator

func (v Value) Iterator() *Iterator

Iterator will create and return iterator struct

func (Value) KindOneOf

func (t Value) KindOneOf(k ...reflect.Kind) bool

KindOneOf is method to compare type against multiple reflect.Type with logical OR

func (Value) Len

func (v Value) Len() (length int)

Len try to get length of object. It will wrap original value into new value so interface{} can work

func (Value) Search

func (v Value) Search(iterator SearchFunc) *KeyValue

Search will iterate over struct map or slice providing key value of every element and return first result when iterator return true

func (Value) SearchIndex

func (v Value) SearchIndex(compare Comparator, element interface{}) int

SearchIndex will search for specific element in list and return index. If not found returns -1. it panics if list is not searchable

func (Value) SearchKey

func (v Value) SearchKey(compare Comparator, element interface{}) *KeyValue

SearchKey will search for specific key in struct slice or map

func (Value) SearchValue

func (v Value) SearchValue(compare Comparator, element interface{}) *KeyValue

SearchValue will search for specific value in struct slice or map

func (Value) String

func (v Value) String() string

String returns

func (Value) Type

func (v Value) Type() Type

Type will wrap original reflect.Type to Type

func (Value) Untyped

func (v Value) Untyped() Value

Untyped will return value it self if not nil. If nil rather then using value's nil it uses raw nil. This is useful in cases where you want insted of (*string)(nil) just nil

func (Value) Zero

func (v Value) Zero() Value

Zero will return zero of its own type

func (Value) Zeroer

func (v Value) Zeroer() (Zeroer, bool)

Zeroer is like assertion with adition check if value can be used for type assertion to Zeroer

type ValueSorter

type ValueSorter []Value

ValueSorter will sort values in slice this is good for searching maps and structs which don't have to preserve order

func (ValueSorter) Len

func (sorter ValueSorter) Len() int

Len return ren of slice

func (ValueSorter) Less

func (sorter ValueSorter) Less(i, j int) bool

Less will check if value is 'less' then other

func (ValueSorter) Sort

func (sorter ValueSorter) Sort()

Sort will sort values in slice

func (ValueSorter) Swap

func (sorter ValueSorter) Swap(i, j int)

Swap performs swaping of values in slice

type Zeroer

type Zeroer interface {
	IsZero() bool
}

Zeroer ...

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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