Query nested properties & arrays using dot notation to get/set values.
Creates objects on pointers & extends array if value not present.
Import
go get -u github.com/markshapiro/property-query
import (
query "github.com/markshapiro/property-query"
)
Usage
type MyStruct struct {
Num int
Text string
Nested NestedStruct
Arr []string
PtrToText *string
PtrToNested *NestedStruct
}
type NestedStruct struct {
Num int
Text string
}
obj := MyStruct{
Arr: []string{"a", "b", "c"},
}
// to set value
err = query.Set(&obj, "num", 123)
err = query.Set(&obj, "text", "abc")
// to get value as interface{}
value, _, err := query.Get(&obj, "text")
query.Set(&obj, "nested.num", 123)
query.Set(&obj, "nested.text", "abc")
// property name can start with capitalized leter
query.Set(&obj, "Nested.Text", "abc")
query.Set(&obj, "nested.Text", "abc")
Set(&obj, "arr[0]", "d")
query.Set(&obj, "arr[-2]", "e") // will set 2nd last index
query.Set(&obj, "arr[10]", "f") // will extend array to size 11
text := "some text"
query.Set(&obj, "PtrToText", &text)
query.Set(&obj, "PtrToText", text) // will work too
// will initiate empty struct if PtrToNested initially points to nil
query.Set(&obj, "PtrToNested.num", 123)
filters := make(map[string]func(interface{}) bool)
filters["myFilter"] = func(val interface{}) bool {
str := val.(string)
return str == "a" || str == "c"
}
// will set new value to elements that match myFilter function
query.Set(&obj, "Arr[myFilter]", "new value", filters)
filters["myFilter2"] = func(val interface{}) bool {
str := val.(string)
return len(str) > 1
}
// will get array of interface{} of elements that match myFilter2
_, arr, err := query.Get(&obj, "Arr[myFilter2]", filters)