Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/theduke/go-reflector
Reflection library for Go to make working with reflection safer and easier.
https://github.com/theduke/go-reflector
Last synced: about 2 months ago
JSON representation
Reflection library for Go to make working with reflection safer and easier.
- Host: GitHub
- URL: https://github.com/theduke/go-reflector
- Owner: theduke
- License: mit
- Created: 2015-10-31T12:10:44.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2015-11-04T14:24:41.000Z (about 9 years ago)
- Last Synced: 2024-10-31T04:50:39.311Z (about 2 months ago)
- Language: Go
- Size: 180 KB
- Stars: 6
- Watchers: 4
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# go-reflector
Go reflector is a library that makes working with reflection in Go easier and safer.
Features:
* Safe methods that do not panic, but return errors or nil
* .IsNumeric(), .IsNil(), .IsZero(), .IsEmpty(), ...
* Easily convert between different types.
* Easily create and work with slices.
* Easily create and work with structs.
* Compare arbitrary values with operators (=, !=, <, <=, >, >=)
* Recursive .ToMap() and .FromMap() for structs
* Filter slices with filter functions.
* Sort arrays by arbitrary functions
* Easily sort arrays of structs or maps by field.One principal of the library is to almost never panic, but return nil values or errors instead,
unlike the reflect package of the standard library.
Note that it may panic when using methods prefixed with **Must**.## Api Documenation
Detailed docs on all methods can be found on [GoDoc](https://godoc.org/github.com/theduke/go-reflector)
## Install
```bash
go get github.com/theduke/go-reflector
```## Usage
### Basics
```go
import "github.com/theduke/go-reflector"r := reflector.Reflect(0)
// Note: reflector.R(x) is a convenient alias for reflector.Reflect(x).
r = reflector.R(0)
r.IsNumeric() // => true
r.IsNil() // => false
r.IsZero() // => true
r.Len() // => 0 (not an iterable!)// Convert to another type.
r.ConvertTo("") // => "0"// Convert to float64.
val, err := r.ConvertTo(float64(0)) // => 0.0// Convert string to int.
val, err = reflector.R("22").ConvertTo(0) // => 22// Convert float64 to int.
val, err = reflector.R(float64(10.0)).ConvertTo(0) // => 10// Convert string to time.Time!
val, err := reflector.R("2012-05-23T18:30:00.000-05:00").ConvertTo(time.Time{}) // => time.Time{}// Iterables.
r := reflector.R([]int{1,2,3})
r.IsEmpty() // => false
r.IsMap() // => false
r.IsSlice() // => true
r.Len() // => 3
r.Equals(22) // => false
r.Equals([]int{1,2,3}) // => true
```### Working with slices.
```go
import "github.com/theduke/go-reflector"s := reflector.R([]int{1,2,3}).MustSlice()
s.Type() // => reflect.Type
s.Len() // => 3
// Get a Reflector for an item in the slice.
s.Index(0) // => Reflector
// Out of range index.
s.Index(22) // => nil
// Get the value at index x
s.IndexValue(0) // => 1
// Out of range index.
s.IndexValue(44) // => nil// Iterate over all items in the slice.
for _, item := range s.Items() {
val := item.Interface()
}// Convert int slice to float slice.
rr, err := s.ConvertTo(float64(0))
floatSlice := rr.Interface() // []float64{1.0, 2.0, 3.0}// Creating new uint slice.
n := reflector.R(uint(0)).NewSlice()
err := n.AppendValue(uint(4), uint(5), uint(6))
n.Len() // => 3
n.Interface() // => []uint{4, 5, 6}// When trying to append wrong type.
err := n.AppendValue("2") // => err: type_mismatch// Updating existing slices.
var intSlice []int
// Note: must pass pointer to slice!
r := reflector.R(&intSlice).MustSlice()
err := r.AppendValue(1, 2)
len(intSlice) // => 2
```### Working with structs
```go
type TestStruct struct {
Field1 int
Field2 string
}t := TestStruct{
Field1: 1,
Field2: "x"
}r := reflector.R(t).MustStruct()
// Check field presence.
r.HasField("Field1") // => true
r.HasField("X") // => false// Get field values.
val, err := r.FieldValue("Field1") // => interface{}(1), nil
val, err = r.FieldValue("X") // => nil, err_inexistant_field// Get field values with no error.
r.UFieldValue("Field1") // => interface{}(1), nil
r.UFieldValue("X") // => nil// Getting reflected fields.
r.Field("Field1").Type() // => reflect.Type
r.Field("Field1").IsZero() // => false
r.Field("Field1").Interface() // => interface{}(1)// Iterating over all fields:
for name, field := range r.Fields() {
if field.IsString() {
...
}
}// Recursively (!) convert struct to map.
r.ToMap() // => map[string]interface{}{"Field1": 1, "Field2": "x"}// Updating field values.
t := TestStruct{
Field1: 1,
Field2: "x"
}// Notice that you must pass a pointer!
r := reflector.R(&t).MustStruct()err := r.SetFieldValue("Field1", 44) // => nil
err := r.SetFieldValue("Field2", 44) // => err_type_mismatch
err := r.SetFieldValue("FieldXX", "x") // => err_unknown_field// Auto-convert values
// Auto-convert from string to int.
// Pass true for auto-convert.
err := r.SetFieldValue("Field1", "44", true) // => nil// Impossible conversion.
err := r.SetFieldValue("Field1", []int{22}, true) // => err_unconvertable_type// Load fields from a map.
data := map[string]interface{
"Field1": float64(0),
"Field2": "string",
}// Pass true for auto-convert.
err := r.FromMap(data, true) // => nil
```### Comparing values
```go
r := reflector.R(20)
flag, err := r.CompareTo(float64(20), "=") // => true, nil
flag, err := r.CompareTo(uint(30), "<") // => true, nil
flag, err := r.CompareTo("20", "!=") // => false, nil// Invalid comparisons.
flag, err := r.CompareTo([]int{}, "=") // => false, err_incomparable_types
```### Filtering
### Sorting
#### Sort an array of structs, struct pointers or maps by field name.
```go
type S struct {
Int int
}s := []testStruct{
S{Int: 87},
S{Int: 1000},
S{Int: 5},
S{Int: 800},
S{Int: 2},
}r := reflector.R(s).MustSlice()
err := r.SortByField("Int")```
## Additional information
### Changelog
[Changelog](https://github.com/theduke/go-reflector/blob/master/CHANGELOG.md)
### Versioning
This project follows [SemVer](http://semver.org/).
### License
This project is under the [MIT license](https://opensource.org/licenses/MIT).
### Tests
Tests are written in [Ginkgo]()
Test coverage is pretty good, but not perfect (~90%).To run tests yourself:
```bash
go get github.com/onsi/ginkgo/ginkgo # installs the ginkgo CLI
go get github.com/onsi/gomega # fetches the matcher librarycd /path/to/go/reflector
go test -cover
```