diff --git a/cmd/strucmd/main.go b/cmd/strucmd/main.go
deleted file mode 100644
index aa46a6d5..00000000
--- a/cmd/strucmd/main.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package main
-
-import (
- "fmt"
-)
-
-func main() {
- fmt.Println("NOT IMPLEMENTED YET")
-}
diff --git a/dynamicstruct/decoder/benchmark_test.go b/dynamicstruct/decoder/benchmark_test.go
index 18651cb8..cb2e6e2b 100644
--- a/dynamicstruct/decoder/benchmark_test.go
+++ b/dynamicstruct/decoder/benchmark_test.go
@@ -6,6 +6,310 @@ import (
. "github.com/goldeneggg/structil/dynamicstruct/decoder"
)
+var (
+ singleJSON = []byte(`
+{
+ "null_field":null,
+ "string_field":"かきくけこ",
+ "int_field":45678,
+ "float64_field":9.876,
+ "bool_field":false,
+ "struct_ptr_field":{
+ "key":"hugakey",
+ "value":"hugavalue"
+ },
+ "array_string_field":[
+ "array_str_1",
+ "array_str_2"
+ ],
+ "array_struct_field":[
+ {
+ "kkk":"kkk1",
+ "vvvv":"vvv1"
+ },
+ {
+ "kkk":"kkk2",
+ "vvvv":"vvv2"
+ },
+ {
+ "kkk":"kkk3",
+ "vvvv":"vvv3"
+ }
+ ]
+}
+`)
+
+ arrayJSON = []byte(`
+[
+ {
+ "null_field":null,
+ "string_field":"かきくけこ",
+ "int_field":45678,
+ "float64_field":9.876,
+ "bool_field":false,
+ "struct_ptr_field":{
+ "key":"hugakey",
+ "value":"hugavalue"
+ },
+ "array_string_field":[
+ "array_str_1",
+ "array_str_2"
+ ],
+ "array_struct_field":[
+ {
+ "kkk":"kkk1",
+ "vvvv":"vvv1"
+ },
+ {
+ "kkk":"kkk2",
+ "vvvv":"vvv2"
+ },
+ {
+ "kkk":"kkk3",
+ "vvvv":"vvv3"
+ }
+ ]
+ },
+ {
+ "null_field":null,
+ "string_field":"さしすせそ",
+ "int_field":7890,
+ "float64_field":4.99,
+ "bool_field":true,
+ "struct_ptr_field":{
+ "key":"hugakeyXXX",
+ "value":"hugavalueXXX"
+ },
+ "array_string_field":[
+ "array_str_111",
+ "array_str_222"
+ ],
+ "array_struct_field":[
+ {
+ "kkk":"kkk99",
+ "vvvv":"vvv99"
+ },
+ {
+ "kkk":"kkk999",
+ "vvvv":"vvv999"
+ },
+ {
+ "kkk":"kkk9999",
+ "vvvv":"vvv9999"
+ }
+ ]
+ }
+]
+`)
+
+ singleYAML = []byte(`
+null_field: null
+string_field: かきくけこ
+int_field: 45678
+float64_field: 9.876
+bool_field: false
+struct_ptr_field:
+ key: hugakey
+ value: hugavalue
+array_string_field:
+ - array_str_1
+ - array_str_2
+array_struct_field:
+ - kkk: kkk1
+ vvvv: vvv1
+ - kkk: kkk2
+ vvvv: vvv2
+ - kkk: kkk3
+ vvvv: vvv3
+`)
+
+ arrayYAML = []byte(`
+- null_field: null
+ string_field: かきくけこ
+ int_field: 45678
+ float64_field: 9.876
+ bool_field: false
+ struct_ptr_field:
+ key: hugakey
+ value: hugavalue
+ array_string_field:
+ - array_str_1
+ - array_str_2
+ array_struct_field:
+ - kkk: kkk1
+ vvvv: vvv1
+ - kkk: kkk2
+ vvvv: vvv2
+ - kkk: kkk3
+ vvvv: vvv3
+- null_field: null
+ string_field: さしすせそ
+ int_field: 7890
+ float64_field: 4.99
+ bool_field: true
+ struct_ptr_field:
+ key: hugakeyXXX
+ value: hugavalueXXX
+ array_string_field:
+ - array_str_111
+ - array_str_222
+ array_struct_field:
+ - kkk: kkk99
+ vvvv: vvv99
+ - kkk: kkk999
+ vvvv: vvv999
+ - kkk: kkk9999
+ vvvv: vvv9999
+`)
+
+ //lint:ignore U1000 It's ok because this is for the future.
+ singleTOML = []byte(`
+string_field = "かきくけこ,"
+int_field = 45678
+float64_field = "9.876,"
+bool_field = false
+array_string_field = ["array_str_1", "array_str_2"]
+
+[struct_ptr_field]
+ key = "hugakey"
+ value = "hugavalue"
+
+[[array_struct_field]]
+ kkk = "kkk1"
+ vvvv = "vvv1"
+
+[[array_struct_field]]
+ kkk = "kkk2"
+ vvvv = "vvv2"
+
+[[array_struct_field]]
+ kkk = "kkk3"
+ vvvv = "vvv3"
+`)
+
+ //lint:ignore U1000 It's ok because this is for the future.
+ singleXML = []byte(`
+
+
+
+ かきくけこ
+ 45678
+ 9.876
+ false
+
+ hugakey
+ hugavalue
+
+ array_str_1
+ array_str_2
+
+ kkk1
+ vvv1
+
+
+ kkk2
+ vvv2
+
+
+ kkk3
+ vvv3
+
+
+`)
+
+ //lint:ignore U1000 It's ok because this is for the future.
+ arrayXML = []byte(`
+
+
+ <0>
+
+ かきくけこ
+ 45678
+ 9.876
+ false
+
+ hugakey
+ hugavalue
+
+ array_str_1
+ array_str_2
+
+ kkk1
+ vvv1
+
+
+ kkk2
+ vvv2
+
+
+ kkk3
+ vvv3
+
+ 0>
+ <1>
+
+ さしすせそ
+ 7890
+ 4.99
+ true
+
+ hugakeyXXX
+ hugavalueXXX
+
+ array_str_111
+ array_str_222
+
+ kkk99
+ vvv99
+
+
+ kkk999
+ vvv999
+
+
+ kkk9999
+ vvv9999
+
+ 1>
+
+`)
+
+ //lint:ignore U1000 It's ok because this is for the future.
+ singleHCL = []byte(`
+null_field =
+
+string_field = "かきくけこ,"
+
+int_field = 45678
+
+float64_field = "9.876,"
+
+bool_field = false
+
+struct_ptr_field = {
+ key = "hugakey"
+ value = "hugavalue"
+}
+
+array_string_field = ["array_str_1", "array_str_2"]
+
+array_struct_field = {
+ kkk = "kkk1"
+ vvvv = "vvv1"
+}
+
+"array_struct_field" = {
+ kkk = "kkk2"
+ vvvv = "vvv2"
+}
+
+array_struct_field = {
+ kkk = "kkk3"
+ vvvv = "vvv3"
+}
+`)
+)
+
func BenchmarkFromJSON_singleJSON(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
@@ -74,6 +378,34 @@ func BenchmarkDynamicStruct_arrayJSON_nest_useTag(b *testing.B) {
}
}
+func BenchmarkJSONToGetter_singleJSON_nonNest(b *testing.B) {
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ _, _ = JSONToGetter(singleJSON, false)
+ }
+}
+
+func BenchmarkJSONToGetter_singleJSON_nest(b *testing.B) {
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ _, _ = JSONToGetter(singleJSON, true)
+ }
+}
+
+func BenchmarkJSONToGetter_arrayJSON_nonNest(b *testing.B) {
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ _, _ = JSONToGetter(arrayJSON, false)
+ }
+}
+
+func BenchmarkJSONToGetter_arrayJSON_nest(b *testing.B) {
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ _, _ = JSONToGetter(arrayJSON, true)
+ }
+}
+
func BenchmarkFromYAML_singleYAML(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
@@ -142,34 +474,6 @@ func BenchmarkDynamicStruct_arrayYAML_nest_useTag(b *testing.B) {
}
}
-func BenchmarkJSONToGetter_singleJSON_nonNest(b *testing.B) {
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- _, _ = JSONToGetter(singleJSON, false)
- }
-}
-
-func BenchmarkJSONToGetter_singleJSON_nest(b *testing.B) {
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- _, _ = JSONToGetter(singleJSON, true)
- }
-}
-
-func BenchmarkJSONToGetter_arrayJSON_nonNest(b *testing.B) {
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- _, _ = JSONToGetter(arrayJSON, false)
- }
-}
-
-func BenchmarkJSONToGetter_arrayJSON_nest(b *testing.B) {
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- _, _ = JSONToGetter(arrayJSON, true)
- }
-}
-
func BenchmarkYAMLToGetter_singleYAML_nonNest(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
diff --git a/dynamicstruct/decoder/data_type.go b/dynamicstruct/decoder/data_type.go
index 6f6ccb3b..3f637c98 100644
--- a/dynamicstruct/decoder/data_type.go
+++ b/dynamicstruct/decoder/data_type.go
@@ -4,6 +4,9 @@ import (
"encoding/json"
"fmt"
+ "github.com/hashicorp/hcl/v2"
+ "github.com/hashicorp/hcl/v2/hclsimple"
+ "github.com/zclconf/go-cty/cty"
"gopkg.in/yaml.v3"
)
@@ -12,21 +15,13 @@ import (
type dataType int
const (
- // TypeJSON is the type sign of JSON
typeJSON dataType = iota
-
- // TypeYAML is the type sign of YAML
typeYAML
+ typeHCL
// FIXME: futures as follows
-
- // TypeXML is the type sign of XML
// TypeXML
-
- // TypeTOML is the type sign of TOML
// TypeTOML
-
- // TypeCSV is the type sign of CSV
// TypeCSV
end // end of iota
@@ -35,6 +30,7 @@ const (
var formats = [...]string{
typeJSON: "json",
typeYAML: "yaml",
+ typeHCL: "hcl",
}
func (dt dataType) string() string {
@@ -44,27 +40,101 @@ func (dt dataType) string() string {
return ""
}
-func (dt dataType) unmarshal(data []byte) (interface{}, error) {
- var intf interface{}
- err := dt.unmarshalWithIPtr(data, &intf)
- return intf, err
-}
+func (dt dataType) unmarshal(data []byte) (ret interface{}, err error) {
+ switch dt {
+ case typeHCL:
+ // Note: hclsimple.Decode supports only pointer of map or struct.
+ var m map[string]interface{}
+ err = hclsimple.Decode("example.hcl", data, nil, &m)
+ if err != nil {
+ return nil, err
+ }
+ dec, err := decodeHCL(data)
+ if err != nil {
+ return nil, err
+ }
+ return interface{}(dec), nil
+ default:
+ err = dt.unmarshalWithPtr(data, &ret)
+ }
-func (dt dataType) unmarshalWithIPtr(data []byte, iptr interface{}) error {
- var err error
+ return
+}
+func (dt dataType) unmarshalWithPtr(data []byte, iptr interface{}) (err error) {
switch dt {
case typeJSON:
- // Note: iptr should be "map[string]interface{}"
err = json.Unmarshal(data, iptr)
case typeYAML:
- // Note: iptr should be "map[interface{}]interface{}" using gopkg.in/yaml.v2 package
err = yaml.Unmarshal(data, iptr)
default:
err = fmt.Errorf("invalid datatype for Unmarshal: %v", dt)
}
- return err
+ return
+}
+
+func decodeHCL(data []byte) (map[string]interface{}, error) {
+ // Note: hclsimple.Decode supports only pointer of map or struct.
+ var m map[string]interface{}
+ err := hclsimple.Decode("example.hcl", data, nil, &m)
+ if err != nil {
+ return m, err
+ }
+
+ decoded := make(map[string]interface{}, len(m))
+ for k, v := range m {
+ attr, ok := v.(*hcl.Attribute)
+ if !ok {
+ return decoded, fmt.Errorf("%q field can not cast to *hcl.Attribute. v = %v", k, v)
+ }
+
+ ctyVal, _ := attr.Expr.Value(nil)
+ decoded[k], err = convCtyToGo(ctyVal)
+ if err != nil {
+ return decoded, err
+ }
+ }
+
+ return decoded, nil
+}
+
+func convCtyToGo(ctyVal cty.Value) (interface{}, error) {
+ var err error
+
+ ctyType := ctyVal.Type()
+ if ctyType == cty.String {
+ return ctyVal.AsString(), nil
+ } else if ctyType == cty.Number {
+ return ctyVal.AsBigFloat(), nil
+ } else if ctyType == cty.Bool {
+ return ctyVal.True(), nil
+ } else if ctyType.IsTupleType() {
+ vals := ctyVal.AsValueSlice()
+ ret := make([]interface{}, len(vals))
+ for i, v := range vals {
+ ret[i], err = convCtyToGo(v)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return ret, nil
+ } else if ctyType.IsObjectType() {
+ valM := ctyVal.AsValueMap()
+ retM := make(map[string]interface{}, len(valM))
+ for k, v := range valM {
+ retM[k], err = convCtyToGo(v)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return retM, nil
+ } else if ctyType == cty.DynamicPseudoType {
+ // FIXME: just support only null?
+ return nil, nil
+ } else {
+ return nil, fmt.Errorf("unsupported ctyType: %v", ctyType)
+ }
}
// TODO: add tests and examples
@@ -72,10 +142,8 @@ func (dt dataType) unmarshalWithIPtr(data []byte, iptr interface{}) error {
func (dt dataType) marshal(m map[string]interface{}) (data []byte, err error) {
switch dt {
case typeJSON:
- // Note: v is expected to be "map[string]interface{}"
data, err = json.Marshal(m)
case typeYAML:
- // Note: v is expected to be converted from "map[interface{}]interface{}" to "map[string]interface{}"
data, err = yaml.Marshal(m)
default:
err = fmt.Errorf("invalid datatype for Marshal: %v", dt)
diff --git a/dynamicstruct/decoder/decoder.go b/dynamicstruct/decoder/decoder.go
index 02b5b66b..cdfd2881 100644
--- a/dynamicstruct/decoder/decoder.go
+++ b/dynamicstruct/decoder/decoder.go
@@ -2,6 +2,7 @@ package decoder
import (
"fmt"
+ "math/big"
"github.com/iancoleman/strcase"
@@ -11,70 +12,66 @@ import (
// Decoder is the struct that decodes some marshaled data like JSON and YAML.
type Decoder struct {
- dt dataType
- orgData []byte // original data
- orgIntf interface{} // unmarshaled interface from original data
- strKeyMap map[string]interface{} // string key map for decoding to DymanicStruct
- ds *dynamicstruct.DynamicStruct
- dsi interface{} // unmarshaled result from data to DynamicStruct
+ typ dataType
+ data []byte
+ intf interface{}
+ m map[string]interface{}
+ ds *dynamicstruct.DynamicStruct
}
-func newDecoder(data []byte, dt dataType) (*Decoder, error) {
- unm, err := dt.unmarshal(data)
+// FromJSON returns a concrete Decoder for JSON.
+func FromJSON(data []byte) (*Decoder, error) {
+ return newDecoder(data, typeJSON)
+}
+
+// FromYAML returns a concrete Decoder for YAML.
+func FromYAML(data []byte) (*Decoder, error) {
+ return newDecoder(data, typeYAML)
+}
+
+// FromHCL returns a concrete Decoder for HCL.
+func FromHCL(data []byte) (*Decoder, error) {
+ return newDecoder(data, typeHCL)
+}
+
+// FromXML returns a concrete Decoder for XML.
+// FIXME: This function is still a future candidate (returned error now)
+func FromXML(data []byte) (*Decoder, error) {
+ return newDecoder(data, end) // FIXME: "end" is provisional type
+}
+
+func newDecoder(data []byte, typ dataType) (*Decoder, error) {
+ intf, err := typ.unmarshal(data)
if err != nil {
return nil, err
}
- dec := &Decoder{
- dt: dt,
- orgData: data,
- orgIntf: unm,
- strKeyMap: make(map[string]interface{}),
- }
-
- switch t := dec.orgIntf.(type) {
+ m := make(map[string]interface{})
+ switch t := intf.(type) {
case map[string]interface{}:
// JSON
- dec.strKeyMap = t
- // Note: this is dead case with gopkg.in/yaml.v3 (but alive with v2)
- // case map[interface{}]interface{}:
- // // YAML
- // dec.strKeyMap = toStringKeyMap(t)
+ m = t
case []interface{}:
if len(t) > 0 {
// The items in the array must be same for all elements.
// So the first element is used to process
switch tt := t[0].(type) {
case map[string]interface{}:
- dec.strKeyMap = tt
- // Note: this is dead case with gopkg.in/yaml.v3 (but alive with v2)
- // case map[interface{}]interface{}:
- // dec.strKeyMap = toStringKeyMap(tt)
+ m = tt
default:
return nil, fmt.Errorf("unexpected type of t[0] [%v]", tt)
}
}
default:
- return nil, fmt.Errorf("unexpected type of dec.orgIntf [%v]", t)
+ return nil, fmt.Errorf("unexpected type of unmashalled interface [%v]", t)
}
- return dec, nil
-}
-
-// FromJSON returns a concrete Decoder for JSON.
-func FromJSON(data []byte) (*Decoder, error) {
- return newDecoder(data, typeJSON)
-}
-
-// FromYAML returns a concrete Decoder for YAML.
-func FromYAML(data []byte) (*Decoder, error) {
- return newDecoder(data, typeYAML)
-}
-
-// FromXML returns a concrete Decoder for XML.
-// FIXME: This function is still a future candidate (returned error now)
-func FromXML(data []byte) (*Decoder, error) {
- return newDecoder(data, end) // FIXME: "end" is provisional type
+ return &Decoder{
+ typ: typ,
+ data: data,
+ intf: intf,
+ m: m,
+ }, nil
}
// JSONToGetter returns a structil.Getter with a decoded JSON via DynamicStruct.
@@ -97,6 +94,28 @@ func YAMLToGetter(data []byte, nest bool) (*structil.Getter, error) {
return d.dsToGetter(nest)
}
+// FIXME: HCL decode method supports only struct pointer or map pointer
+// func HCLToGetter(data []byte, nest bool) (*structil.Getter, error) {
+// d, err := FromHCL(data)
+// if err != nil {
+// return nil, fmt.Errorf("fail to HCLToGetter: %w", err)
+// }
+
+// return d.dsToGetter(nest)
+// }
+
+// DynamicStruct returns a decoded DynamicStruct with unmarshaling data to DynamicStruct interface.
+func (d *Decoder) DynamicStruct(nest bool, useTag bool) (*dynamicstruct.DynamicStruct, error) {
+ var err error
+
+ d.ds, err = d.toDsFromStringMap(d.m, nest, useTag)
+ if err != nil {
+ return nil, err
+ }
+
+ return d.ds, err
+}
+
func (d *Decoder) dsToGetter(nest bool) (*structil.Getter, error) {
ds, err := d.DynamicStruct(nest, true)
if err != nil {
@@ -112,50 +131,20 @@ func (d *Decoder) dsToGetter(nest bool) (*structil.Getter, error) {
}
func (d *Decoder) decodeToDynamicStruct(ds *dynamicstruct.DynamicStruct) (interface{}, error) {
- // toDsFromStringMap() method uses "Build()" method and this means that ds is build by pointer-mode
- // So ds.NewInterface() returns a struct *pointer*
- d.dsi = ds.NewInterface()
-
- // must use "d.strKeyMap" (not "d.orgIntf"). because key of "d.orgIntf" is not string but interface{}
- data, err := d.dt.marshal(d.strKeyMap)
+ data, err := d.typ.marshal(d.m)
if err != nil {
- return nil, fmt.Errorf("fail to d.dt.marshal: %w", err)
- }
-
- // must use "d.dsi" (not "&d.dsi"). because "d.dsi" is pointer
- // if use "&.d.dsi", unmarshal result is not struct but map[interface{}]interface when dt is YAML
- if err := d.dt.unmarshalWithIPtr(data, d.dsi); err != nil {
- return nil, fmt.Errorf("fail to d.dt.unmarshalWithIPtr: %w", err)
+ return nil, fmt.Errorf("fail to d.typ.marshal: %w", err)
}
- return d.dsi, nil
-}
-
-// OrgData returns an original data as []byte.
-func (d *Decoder) OrgData() []byte {
- return d.orgData
-}
-
-// DynamicStruct returns a decoded DynamicStruct with unmarshaling data to DynamicStruct interface.
-func (d *Decoder) DynamicStruct(nest bool, useTag bool) (*dynamicstruct.DynamicStruct, error) {
- var err error
-
- // d.ds, err = d.toDs(d.orgIntf, nest, useTag)
- d.ds, err = d.toDs(d.strKeyMap, nest, useTag)
+ // ds.NewInterface() returns a struct *pointer*
+ dsi := ds.NewInterface()
+ // must use "dsi" (not "&dsi"). because "dsi" is pointer
+ err = d.typ.unmarshalWithPtr(data, dsi)
if err != nil {
- return nil, err
- }
-
- return d.ds, err
-}
-
-func (d *Decoder) toDs(i interface{}, nest bool, useTag bool) (*dynamicstruct.DynamicStruct, error) {
- switch t := i.(type) {
- case map[string]interface{}:
- return d.toDsFromStringMap(t, nest, useTag)
+ return nil, fmt.Errorf("fail to d.typ.unmarshalWithPtr: %w", err)
}
- return nil, fmt.Errorf("unsupported type [%T] for toDs", i)
+ return dsi, nil
}
func (d *Decoder) toDsFromStringMap(m map[string]interface{}, nest bool, useTag bool) (*dynamicstruct.DynamicStruct, error) {
@@ -172,7 +161,7 @@ func (d *Decoder) toDsFromStringMap(m map[string]interface{}, nest bool, useTag
// See: https://golang.org/pkg/encoding/json/#Marshal
// See: https://m-zajac.github.io/json2go/
if useTag {
- tag = fmt.Sprintf(`%s:"%s"`, d.dt.string(), k)
+ tag = fmt.Sprintf(`%s:"%s"`, d.typ.string(), k)
}
// FIXME: the first character of k should be only alpha-numeric
@@ -235,6 +224,9 @@ func (d *Decoder) toDsFromStringMap(m map[string]interface{}, nest bool, useTag
// YAML support
case nil:
b = b.AddInterfaceWithTag(name, false, tag)
+ // HCL support
+ case *big.Float:
+ b = b.AddFloat64WithTag(name, tag)
default:
return nil, fmt.Errorf("unsupported type of map-value. key = [%s] value = %#v", k, value)
}
@@ -273,43 +265,3 @@ func (d *Decoder) addForStringMap(
return b, nil
}
-
-// Note: this is dead case with gopkg.in/yaml.v3 (but alive with v2)
-// convert map[interface{}]interface{} to map[string]interface{}
-// func toStringKeyMap(mapii map[interface{}]interface{}) map[string]interface{} {
-// mapsi := make(map[string]interface{})
-// for k, v := range mapii {
-// switch vt := v.(type) {
-// case []interface{}:
-// // for nest array
-// mapsi[fmt.Sprintf("%v", k)] = fromArrayToMapValue(vt)
-// case map[interface{}]interface{}:
-// // for nest object
-// mapsi[fmt.Sprintf("%v", k)] = toStringKeyMap(vt)
-// default:
-// mapsi[fmt.Sprintf("%v", k)] = v
-// }
-// }
-
-// return mapsi
-// }
-
-// Note: this is dead case with gopkg.in/yaml.v3 (but alive with v2)
-// func fromArrayToMapValue(ia []interface{}) interface{} {
-// resIa := make([]interface{}, 0, len(ia))
-// for _, iv := range ia {
-// switch ivt := iv.(type) {
-// case []interface{}:
-// // for nest array
-// resIa = append(resIa, fromArrayToMapValue(ivt))
-// case map[interface{}]interface{}:
-// // for nest object
-// // !!! this is important process for map[interface{}]interface{} to map[string]interface{} for JSON unmarshaling
-// resIa = append(resIa, toStringKeyMap(ivt))
-// default:
-// resIa = append(resIa, ivt)
-// }
-// }
-
-// return resIa
-// }
diff --git a/dynamicstruct/decoder/decoder_test.go b/dynamicstruct/decoder/decoder_test.go
index 6eefbfe1..78955f05 100644
--- a/dynamicstruct/decoder/decoder_test.go
+++ b/dynamicstruct/decoder/decoder_test.go
@@ -12,315 +12,8 @@ import (
const (
typeJSON int = iota
typeYAML
- typeXML
-)
-
-var (
- singleJSON = []byte(`
-{
- "null_field":null,
- "string_field":"かきくけこ",
- "int_field":45678,
- "float32_field":9.876,
- "bool_field":false,
- "struct_ptr_field":{
- "key":"hugakey",
- "value":"hugavalue"
- },
- "array_string_field":[
- "array_str_1",
- "array_str_2"
- ],
- "array_struct_field":[
- {
- "kkk":"kkk1",
- "vvvv":"vvv1"
- },
- {
- "kkk":"kkk2",
- "vvvv":"vvv2"
- },
- {
- "kkk":"kkk3",
- "vvvv":"vvv3"
- }
- ]
-}
-`)
-
- arrayJSON = []byte(`
-[
- {
- "null_field":null,
- "string_field":"かきくけこ",
- "int_field":45678,
- "float32_field":9.876,
- "bool_field":false,
- "struct_ptr_field":{
- "key":"hugakey",
- "value":"hugavalue"
- },
- "array_string_field":[
- "array_str_1",
- "array_str_2"
- ],
- "array_struct_field":[
- {
- "kkk":"kkk1",
- "vvvv":"vvv1"
- },
- {
- "kkk":"kkk2",
- "vvvv":"vvv2"
- },
- {
- "kkk":"kkk3",
- "vvvv":"vvv3"
- }
- ]
- },
- {
- "null_field":null,
- "string_field":"さしすせそ",
- "int_field":7890,
- "float32_field":4.99,
- "bool_field":true,
- "struct_ptr_field":{
- "key":"hugakeyXXX",
- "value":"hugavalueXXX"
- },
- "array_string_field":[
- "array_str_111",
- "array_str_222"
- ],
- "array_struct_field":[
- {
- "kkk":"kkk99",
- "vvvv":"vvv99"
- },
- {
- "kkk":"kkk999",
- "vvvv":"vvv999"
- },
- {
- "kkk":"kkk9999",
- "vvvv":"vvv9999"
- }
- ]
- }
-]
-`)
-
- singleYAML = []byte(`
-null_field: null
-string_field: かきくけこ
-int_field: 45678
-float32_field: 9.876
-bool_field: false
-struct_ptr_field:
- key: hugakey
- value: hugavalue
-array_string_field:
- - array_str_1
- - array_str_2
-array_struct_field:
- - kkk: kkk1
- vvvv: vvv1
- - kkk: kkk2
- vvvv: vvv2
- - kkk: kkk3
- vvvv: vvv3
-`)
-
- arrayYAML = []byte(`
-- null_field: null
- string_field: かきくけこ
- int_field: 45678
- float32_field: 9.876
- bool_field: false
- struct_ptr_field:
- key: hugakey
- value: hugavalue
- array_string_field:
- - array_str_1
- - array_str_2
- array_struct_field:
- - kkk: kkk1
- vvvv: vvv1
- - kkk: kkk2
- vvvv: vvv2
- - kkk: kkk3
- vvvv: vvv3
-- null_field: null
- string_field: さしすせそ
- int_field: 7890
- float32_field: 4.99
- bool_field: true
- struct_ptr_field:
- key: hugakeyXXX
- value: hugavalueXXX
- array_string_field:
- - array_str_111
- - array_str_222
- array_struct_field:
- - kkk: kkk99
- vvvv: vvv99
- - kkk: kkk999
- vvvv: vvv999
- - kkk: kkk9999
- vvvv: vvv9999
-`)
-
- //lint:ignore U1000 It's ok because this is for the future.
- singleTOML = []byte(`
-string_field = "かきくけこ,"
-int_field = 45678
-float32_field = "9.876,"
-bool_field = false
-array_string_field = ["array_str_1", "array_str_2"]
-
-[struct_ptr_field]
- key = "hugakey"
- value = "hugavalue"
-
-[[array_struct_field]]
- kkk = "kkk1"
- vvvv = "vvv1"
-
-[[array_struct_field]]
- kkk = "kkk2"
- vvvv = "vvv2"
-
-[[array_struct_field]]
- kkk = "kkk3"
- vvvv = "vvv3"
-`)
-
- //lint:ignore U1000 It's ok because this is for the future.
- singleXML = []byte(`
-
-
-
- かきくけこ
- 45678
- 9.876
- false
-
- hugakey
- hugavalue
-
- array_str_1
- array_str_2
-
- kkk1
- vvv1
-
-
- kkk2
- vvv2
-
-
- kkk3
- vvv3
-
-
-`)
-
- //lint:ignore U1000 It's ok because this is for the future.
- arrayXML = []byte(`
-
-
- <0>
-
- かきくけこ
- 45678
- 9.876
- false
-
- hugakey
- hugavalue
-
- array_str_1
- array_str_2
-
- kkk1
- vvv1
-
-
- kkk2
- vvv2
-
-
- kkk3
- vvv3
-
- 0>
- <1>
-
- さしすせそ
- 7890
- 4.99
- true
-
- hugakeyXXX
- hugavalueXXX
-
- array_str_111
- array_str_222
-
- kkk99
- vvv99
-
-
- kkk999
- vvv999
-
-
- kkk9999
- vvv9999
-
- 1>
-
-`)
-
- //lint:ignore U1000 It's ok because this is for the future.
- singleHCL = []byte(`
-"null_field" =
-
-"string_field" = "かきくけこ,"
-
-"int_field" = 45678
-
-"float32_field" = "9.876,"
-
-"bool_field" = false
-
-"struct_ptr_field" = {
- "key" = "hugakey"
-
- "value" = "hugavalue"
-}
-
-"array_string_field" = ["array_str_1", "array_str_2"]
-
-"array_struct_field" = {
- "kkk" = "kkk1"
-
- "vvvv" = "vvv1"
-}
-
-"array_struct_field" = {
- "kkk" = "kkk2"
-
- "vvvv" = "vvv2"
-}
-
-"array_struct_field" = {
- "kkk" = "kkk3"
-
- "vvvv" = "vvv3"
-}
-`)
+ typeHCL
+ typeXML // FIXME
)
type decoderTest struct {
@@ -347,7 +40,7 @@ func TestDynamicStructJSON(t *testing.T) {
"null_field":null,
"string_field":"かきくけこ",
"int_field":45678,
- "float32_field":9.876,
+ "float64_field":9.876,
"bool_field":false
}
`),
@@ -357,14 +50,14 @@ func TestDynamicStructJSON(t *testing.T) {
wantNumF: 5,
wantDefinition: `type DynamicStruct struct {
BoolField bool
- Float32Field float64
+ Float64Field float64
IntField float64
NullField interface {}
StringField string
}`,
fieldAndNestFields: map[string][]string{
"BoolField": nil,
- "Float32Field": nil,
+ "Float64Field": nil,
"IntField": nil,
"NullField": nil,
"StringField": nil,
@@ -784,7 +477,7 @@ func TestDynamicStructYAML(t *testing.T) {
null_field: null
string_field: かきくけこ
int_field: 45678
-float32_field: 9.876
+float64_field: 9.876
bool_field: false
`),
dt: typeYAML,
@@ -793,14 +486,14 @@ bool_field: false
wantNumF: 5,
wantDefinition: `type DynamicStruct struct {
BoolField bool
- Float32Field float64
+ Float64Field float64
IntField int
NullField interface {}
StringField string
}`,
fieldAndNestFields: map[string][]string{
"BoolField": nil,
- "Float32Field": nil,
+ "Float64Field": nil,
"IntField": nil,
"NullField": nil,
"StringField": nil,
@@ -1078,6 +771,204 @@ string_array_field:
}
}
+func TestDynamicStructHCL(t *testing.T) {
+ t.Parallel()
+
+ tests := []decoderTest{
+ {
+ name: "NoNestWithoutTag",
+ data: []byte(`
+string_field = "かきくけこ"
+int_field = 45678
+float64_field = 9.876
+bool_field = false
+null_field = null
+tuple_str_field = ["str1", "str2", "str3"]
+tuple_mix_field = ["str1", 123, true]
+object_str_field = {
+ key_a = "valA"
+ key_b = "valB"
+}
+object_mix_field = {
+ key_str = "strA"
+ key_num = 876.543
+ key_bool = true
+}
+`),
+ dt: typeHCL,
+ nest: false,
+ useTag: false,
+ wantNumF: 9,
+ wantDefinition: `type DynamicStruct struct {
+ BoolField bool
+ Float64Field float64
+ IntField float64
+ NullField interface {}
+ ObjectMixField map[string]interface {}
+ ObjectStrField map[string]interface {}
+ StringField string
+ TupleMixField []string
+ TupleStrField []string
+}`,
+ },
+ {
+ name: "IsNestWithoutTag",
+ data: []byte(`
+string_field = "かきくけこ"
+int_field = 45678
+float64_field = 9.876
+bool_field = false
+null_field = null
+tuple_str_field = ["str1", "str2", "str3"]
+tuple_mix_field = ["str1", 123, true]
+object_str_field = {
+ key_a = "valA"
+ key_b = "valB"
+}
+object_mix_field = {
+ key_str = "strA"
+ key_num = 876.543
+ key_bool = true
+}
+`),
+ dt: typeHCL,
+ nest: true,
+ useTag: false,
+ wantNumF: 9,
+ wantDefinition: `type DynamicStruct struct {
+ BoolField bool
+ Float64Field float64
+ IntField float64
+ NullField interface {}
+ ObjectMixField struct {
+ KeyBool bool
+ KeyNum float64
+ KeyStr string
+ }
+ ObjectStrField struct {
+ KeyA string
+ KeyB string
+ }
+ StringField string
+ TupleMixField []string
+ TupleStrField []string
+}`,
+ },
+ {
+ name: "IsNestWithTag",
+ data: []byte(`
+string_field = "かきくけこ"
+int_field = 45678
+float64_field = 9.876
+bool_field = false
+null_field = null
+tuple_str_field = ["str1", "str2", "str3"]
+tuple_mix_field = ["str1", 123, true]
+object_str_field = {
+ key_a = "valA"
+ key_b = "valB"
+}
+object_mix_field = {
+ key_str = "strA"
+ key_num = 876.543
+ key_bool = true
+}
+`),
+ dt: typeHCL,
+ nest: true,
+ useTag: true,
+ wantNumF: 9,
+ wantDefinition: `type DynamicStruct struct {
+ BoolField bool ` + "`hcl:\"bool_field\"`" + `
+ Float64Field float64 ` + "`hcl:\"float64_field\"`" + `
+ IntField float64 ` + "`hcl:\"int_field\"`" + `
+ NullField interface {} ` + "`hcl:\"null_field\"`" + `
+ ObjectMixField struct {
+ KeyBool bool ` + "`hcl:\"key_bool\"`" + `
+ KeyNum float64 ` + "`hcl:\"key_num\"`" + `
+ KeyStr string ` + "`hcl:\"key_str\"`" + `
+ } ` + "`hcl:\"object_mix_field\"`" + `
+ ObjectStrField struct {
+ KeyA string ` + "`hcl:\"key_a\"`" + `
+ KeyB string ` + "`hcl:\"key_b\"`" + `
+ } ` + "`hcl:\"object_str_field\"`" + `
+ StringField string ` + "`hcl:\"string_field\"`" + `
+ TupleMixField []string ` + "`hcl:\"tuple_mix_field\"`" + `
+ TupleStrField []string ` + "`hcl:\"tuple_str_field\"`" + `
+}`,
+ },
+ {
+ name: "BracketOnly",
+ data: []byte(`{}`),
+ dt: typeHCL,
+ nest: false,
+ useTag: false,
+ wantNumF: 0,
+ wantDefinition: ``,
+ wantErrorNew: true,
+ },
+ {
+ name: "ArrayBracketOnly",
+ data: []byte(`[]`),
+ dt: typeHCL,
+ nest: false,
+ useTag: false,
+ wantNumF: 0,
+ wantDefinition: ``,
+ wantErrorNew: true,
+ },
+ {
+ name: "OnlyLiteral",
+ data: []byte(`aiueo`),
+ dt: typeHCL,
+ nest: false,
+ useTag: false,
+ wantNumF: 0,
+ wantDefinition: ``,
+ wantErrorNew: true,
+ },
+ {
+ name: "Empty",
+ data: []byte(``),
+ dt: typeHCL,
+ nest: false,
+ useTag: false,
+ wantNumF: 0,
+ wantDefinition: `type DynamicStruct struct {
+}`,
+ },
+ {
+ name: "NullData",
+ data: nil,
+ dt: typeHCL,
+ nest: false,
+ useTag: false,
+ wantNumF: 0,
+ wantDefinition: `type DynamicStruct struct {
+}`,
+ },
+ }
+
+ for _, tt := range tests {
+ tt := tt // See: https://gist.github.com/posener/92a55c4cd441fc5e5e85f27bca008721
+ t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
+
+ dec, err := FromHCL(tt.data)
+ if err != nil {
+ if !tt.wantErrorNew {
+ t.Fatalf("unexpected error is returned from FromHCL: %v", err)
+ }
+ return
+ } else if tt.wantErrorNew {
+ t.Fatalf("error is expected but it does not occur from FromHCL. data: %q", string(tt.data))
+ }
+
+ testCorrectCase(t, tt, dec)
+ })
+ }
+}
+
func TestDynamicStructFixmeXml(t *testing.T) {
t.Parallel()
@@ -1088,7 +979,7 @@ func TestDynamicStructFixmeXml(t *testing.T) {
null_field: null
string_field: かきくけこ
int_field: 45678
-float32_field: 9.876
+float64_field: 9.876
bool_field: false
`),
dt: typeXML,
@@ -1137,10 +1028,6 @@ bool_field: false
func testCorrectCase(t *testing.T, tt decoderTest, dec *Decoder) {
t.Helper()
- if d := cmp.Diff(dec.OrgData(), tt.data); d != "" {
- t.Fatalf("mismatch OrgData: (-got +want)\n%s", d)
- }
-
ds, err := dec.DynamicStruct(tt.nest, tt.useTag)
if err != nil {
if !tt.wantErrorDs {
diff --git a/getter.go b/getter.go
index ba164fae..ac277a94 100644
--- a/getter.go
+++ b/getter.go
@@ -94,27 +94,27 @@ func (g *Getter) Names() []string {
return g.names
}
-func (g *Getter) getSafely(name string) (*getterField, bool) {
+func (g *Getter) getField(name string) (*getterField, bool) {
gf, ok := g.fields[name]
return gf, ok
}
// goroutine-safely and kind-safely access to a getterField by name
-func (g *Getter) getSafelyKindly(name string, kind reflect.Kind) (*getterField, bool) {
- gf, ok := g.getSafely(name)
+func (g *Getter) getFieldKindly(name string, kind reflect.Kind) (*getterField, bool) {
+ gf, ok := g.getField(name)
return gf, ok && gf.isKind(kind)
}
// Has tests whether the original struct has a field named "name".
func (g *Getter) Has(name string) bool {
- _, ok := g.getSafely(name)
+ _, ok := g.getField(name)
return ok
}
// GetType returns the reflect.Type object of the original struct field named "name".
// 2nd return value will be false if the original struct does not have a "name" field.
func (g *Getter) GetType(name string) (reflect.Type, bool) {
- gf, ok := g.getSafely(name)
+ gf, ok := g.getField(name)
if ok {
return gf.typ, true
}
@@ -125,7 +125,7 @@ func (g *Getter) GetType(name string) (reflect.Type, bool) {
// GetValue returns the reflect.Value object of the original struct field named "name".
// 2nd return value will be false if the original struct does not have a "name" field.
func (g *Getter) GetValue(name string) (reflect.Value, bool) {
- gf, ok := g.getSafely(name)
+ gf, ok := g.getField(name)
if ok {
return gf.indirect, true
}
@@ -136,7 +136,7 @@ func (g *Getter) GetValue(name string) (reflect.Value, bool) {
// Get returns the interface of the original struct field named name.
// 2nd return value will be false if the original struct does not have a "name" field.
func (g *Getter) Get(name string) (interface{}, bool) {
- gf, ok := g.getSafely(name)
+ gf, ok := g.getField(name)
if ok {
return gf.intf, true
}
@@ -156,7 +156,7 @@ func (g *Getter) ToMap() map[string]interface{} {
// IsSlice reports whether type of the original struct field named name is slice.
func (g *Getter) IsSlice(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Slice)
+ _, ok := g.getFieldKindly(name, reflect.Slice)
return ok
}
@@ -164,7 +164,7 @@ func (g *Getter) IsSlice(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not slice of interface.
func (g *Getter) Slice(name string) ([]interface{}, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Slice)
+ gf, ok := g.getFieldKindly(name, reflect.Slice)
if !ok {
return nil, false
}
@@ -181,7 +181,7 @@ func (g *Getter) Slice(name string) ([]interface{}, bool) {
// IsBool reports whether type of the original struct field named name is bool.
func (g *Getter) IsBool(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Bool)
+ _, ok := g.getFieldKindly(name, reflect.Bool)
return ok
}
@@ -189,7 +189,7 @@ func (g *Getter) IsBool(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not bool.
func (g *Getter) Bool(name string) (bool, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Bool)
+ gf, ok := g.getFieldKindly(name, reflect.Bool)
if !ok {
return false, false
}
@@ -200,7 +200,7 @@ func (g *Getter) Bool(name string) (bool, bool) {
// IsByte reports whether type of the original struct field named name is byte.
func (g *Getter) IsByte(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Uint8)
+ _, ok := g.getFieldKindly(name, reflect.Uint8)
return ok
}
@@ -208,7 +208,7 @@ func (g *Getter) IsByte(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not byte.
func (g *Getter) Byte(name string) (byte, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Uint8)
+ gf, ok := g.getFieldKindly(name, reflect.Uint8)
if !ok {
return 0, false
}
@@ -219,7 +219,7 @@ func (g *Getter) Byte(name string) (byte, bool) {
// IsBytes reports whether type of the original struct field named name is []byte.
func (g *Getter) IsBytes(name string) bool {
- gf, ok := g.getSafelyKindly(name, reflect.Slice)
+ gf, ok := g.getFieldKindly(name, reflect.Slice)
if !ok {
return false
}
@@ -231,7 +231,7 @@ func (g *Getter) IsBytes(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not []byte.
func (g *Getter) Bytes(name string) ([]byte, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Slice)
+ gf, ok := g.getFieldKindly(name, reflect.Slice)
if !ok {
return nil, false
}
@@ -242,7 +242,7 @@ func (g *Getter) Bytes(name string) ([]byte, bool) {
// IsString reports whether type of the original struct field named name is string.
func (g *Getter) IsString(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.String)
+ _, ok := g.getFieldKindly(name, reflect.String)
return ok
}
@@ -250,7 +250,7 @@ func (g *Getter) IsString(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not string.
func (g *Getter) String(name string) (string, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.String)
+ gf, ok := g.getFieldKindly(name, reflect.String)
if !ok {
return "", false
}
@@ -261,7 +261,7 @@ func (g *Getter) String(name string) (string, bool) {
// IsInt reports whether type of the original struct field named name is int.
func (g *Getter) IsInt(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Int)
+ _, ok := g.getFieldKindly(name, reflect.Int)
return ok
}
@@ -269,7 +269,7 @@ func (g *Getter) IsInt(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not int.
func (g *Getter) Int(name string) (int, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Int)
+ gf, ok := g.getFieldKindly(name, reflect.Int)
if !ok {
return 0, false
}
@@ -280,7 +280,7 @@ func (g *Getter) Int(name string) (int, bool) {
// IsInt8 reports whether type of the original struct field named name is int8.
func (g *Getter) IsInt8(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Int8)
+ _, ok := g.getFieldKindly(name, reflect.Int8)
return ok
}
@@ -288,7 +288,7 @@ func (g *Getter) IsInt8(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not int8.
func (g *Getter) Int8(name string) (int8, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Int8)
+ gf, ok := g.getFieldKindly(name, reflect.Int8)
if !ok {
return 0, false
}
@@ -299,7 +299,7 @@ func (g *Getter) Int8(name string) (int8, bool) {
// IsInt16 reports whether type of the original struct field named name is int16.
func (g *Getter) IsInt16(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Int16)
+ _, ok := g.getFieldKindly(name, reflect.Int16)
return ok
}
@@ -307,7 +307,7 @@ func (g *Getter) IsInt16(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not int16.
func (g *Getter) Int16(name string) (int16, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Int16)
+ gf, ok := g.getFieldKindly(name, reflect.Int16)
if !ok {
return 0, false
}
@@ -318,7 +318,7 @@ func (g *Getter) Int16(name string) (int16, bool) {
// IsInt32 reports whether type of the original struct field named name is int32.
func (g *Getter) IsInt32(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Int32)
+ _, ok := g.getFieldKindly(name, reflect.Int32)
return ok
}
@@ -326,7 +326,7 @@ func (g *Getter) IsInt32(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not int32.
func (g *Getter) Int32(name string) (int32, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Int32)
+ gf, ok := g.getFieldKindly(name, reflect.Int32)
if !ok {
return 0, false
}
@@ -337,7 +337,7 @@ func (g *Getter) Int32(name string) (int32, bool) {
// IsInt64 reports whether type of the original struct field named name is int64.
func (g *Getter) IsInt64(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Int64)
+ _, ok := g.getFieldKindly(name, reflect.Int64)
return ok
}
@@ -345,7 +345,7 @@ func (g *Getter) IsInt64(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not int64.
func (g *Getter) Int64(name string) (int64, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Int64)
+ gf, ok := g.getFieldKindly(name, reflect.Int64)
if !ok {
return 0, false
}
@@ -356,7 +356,7 @@ func (g *Getter) Int64(name string) (int64, bool) {
// IsUint reports whether type of the original struct field named name is uint.
func (g *Getter) IsUint(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Uint)
+ _, ok := g.getFieldKindly(name, reflect.Uint)
return ok
}
@@ -364,7 +364,7 @@ func (g *Getter) IsUint(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not uint.
func (g *Getter) Uint(name string) (uint, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Uint)
+ gf, ok := g.getFieldKindly(name, reflect.Uint)
if !ok {
return 0, false
}
@@ -375,7 +375,7 @@ func (g *Getter) Uint(name string) (uint, bool) {
// IsUint8 reports whether type of the original struct field named name is uint8.
func (g *Getter) IsUint8(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Uint8)
+ _, ok := g.getFieldKindly(name, reflect.Uint8)
return ok
}
@@ -383,7 +383,7 @@ func (g *Getter) IsUint8(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not uint8.
func (g *Getter) Uint8(name string) (uint8, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Uint8)
+ gf, ok := g.getFieldKindly(name, reflect.Uint8)
if !ok {
return 0, false
}
@@ -394,7 +394,7 @@ func (g *Getter) Uint8(name string) (uint8, bool) {
// IsUint16 reports whether type of the original struct field named name is uint16.
func (g *Getter) IsUint16(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Uint16)
+ _, ok := g.getFieldKindly(name, reflect.Uint16)
return ok
}
@@ -402,7 +402,7 @@ func (g *Getter) IsUint16(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not uint16.
func (g *Getter) Uint16(name string) (uint16, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Uint16)
+ gf, ok := g.getFieldKindly(name, reflect.Uint16)
if !ok {
return 0, false
}
@@ -413,7 +413,7 @@ func (g *Getter) Uint16(name string) (uint16, bool) {
// IsUint32 reports whether type of the original struct field named name is uint32.
func (g *Getter) IsUint32(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Uint32)
+ _, ok := g.getFieldKindly(name, reflect.Uint32)
return ok
}
@@ -421,7 +421,7 @@ func (g *Getter) IsUint32(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not uint32.
func (g *Getter) Uint32(name string) (uint32, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Uint32)
+ gf, ok := g.getFieldKindly(name, reflect.Uint32)
if !ok {
return 0, false
}
@@ -432,7 +432,7 @@ func (g *Getter) Uint32(name string) (uint32, bool) {
// IsUint64 reports whether type of the original struct field named name is uint64.
func (g *Getter) IsUint64(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Uint64)
+ _, ok := g.getFieldKindly(name, reflect.Uint64)
return ok
}
@@ -440,7 +440,7 @@ func (g *Getter) IsUint64(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not uint64.
func (g *Getter) Uint64(name string) (uint64, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Uint64)
+ gf, ok := g.getFieldKindly(name, reflect.Uint64)
if !ok {
return 0, false
}
@@ -451,7 +451,7 @@ func (g *Getter) Uint64(name string) (uint64, bool) {
// IsUintptr reports whether type of the original struct field named name is uintptr.
func (g *Getter) IsUintptr(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Uintptr)
+ _, ok := g.getFieldKindly(name, reflect.Uintptr)
return ok
}
@@ -459,7 +459,7 @@ func (g *Getter) IsUintptr(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not uintptr.
func (g *Getter) Uintptr(name string) (uintptr, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Uintptr)
+ gf, ok := g.getFieldKindly(name, reflect.Uintptr)
if !ok {
return 0, false
}
@@ -470,7 +470,7 @@ func (g *Getter) Uintptr(name string) (uintptr, bool) {
// IsFloat32 reports whether type of the original struct field named name is float32.
func (g *Getter) IsFloat32(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Float32)
+ _, ok := g.getFieldKindly(name, reflect.Float32)
return ok
}
@@ -478,7 +478,7 @@ func (g *Getter) IsFloat32(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not float32.
func (g *Getter) Float32(name string) (float32, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Float32)
+ gf, ok := g.getFieldKindly(name, reflect.Float32)
if !ok {
return 0, false
}
@@ -489,7 +489,7 @@ func (g *Getter) Float32(name string) (float32, bool) {
// IsFloat64 reports whether type of the original struct field named name is float64.
func (g *Getter) IsFloat64(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Float64)
+ _, ok := g.getFieldKindly(name, reflect.Float64)
return ok
}
@@ -497,7 +497,7 @@ func (g *Getter) IsFloat64(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not float64.
func (g *Getter) Float64(name string) (float64, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Float64)
+ gf, ok := g.getFieldKindly(name, reflect.Float64)
if !ok {
return 0, false
}
@@ -508,7 +508,7 @@ func (g *Getter) Float64(name string) (float64, bool) {
// IsComplex64 reports whether type of the original struct field named name is []byte.
func (g *Getter) IsComplex64(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Complex64)
+ _, ok := g.getFieldKindly(name, reflect.Complex64)
return ok
}
@@ -516,7 +516,7 @@ func (g *Getter) IsComplex64(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not complex64.
func (g *Getter) Complex64(name string) (complex64, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Complex64)
+ gf, ok := g.getFieldKindly(name, reflect.Complex64)
if !ok {
return 0, false
}
@@ -527,7 +527,7 @@ func (g *Getter) Complex64(name string) (complex64, bool) {
// IsComplex128 reports whether type of the original struct field named name is []byte.
func (g *Getter) IsComplex128(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Complex128)
+ _, ok := g.getFieldKindly(name, reflect.Complex128)
return ok
}
@@ -535,7 +535,7 @@ func (g *Getter) IsComplex128(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not complex128.
func (g *Getter) Complex128(name string) (complex128, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Complex128)
+ gf, ok := g.getFieldKindly(name, reflect.Complex128)
if !ok {
return 0, false
}
@@ -546,7 +546,7 @@ func (g *Getter) Complex128(name string) (complex128, bool) {
// IsUnsafePointer reports whether type of the original struct field named name is []byte.
func (g *Getter) IsUnsafePointer(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.UnsafePointer)
+ _, ok := g.getFieldKindly(name, reflect.UnsafePointer)
return ok
}
@@ -554,7 +554,7 @@ func (g *Getter) IsUnsafePointer(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not unsafe.Pointer.
func (g *Getter) UnsafePointer(name string) (unsafe.Pointer, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.UnsafePointer)
+ gf, ok := g.getFieldKindly(name, reflect.UnsafePointer)
if !ok {
return nil, false
}
@@ -565,31 +565,31 @@ func (g *Getter) UnsafePointer(name string) (unsafe.Pointer, bool) {
// IsMap reports whether type of the original struct field named name is map.
func (g *Getter) IsMap(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Map)
+ _, ok := g.getFieldKindly(name, reflect.Map)
return ok
}
// IsFunc reports whether type of the original struct field named name is func.
func (g *Getter) IsFunc(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Func)
+ _, ok := g.getFieldKindly(name, reflect.Func)
return ok
}
// IsChan reports whether type of the original struct field named name is chan.
func (g *Getter) IsChan(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Chan)
+ _, ok := g.getFieldKindly(name, reflect.Chan)
return ok
}
// IsStruct reports whether type of the original struct field named name is struct.
func (g *Getter) IsStruct(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Struct)
+ _, ok := g.getFieldKindly(name, reflect.Struct)
return ok
}
// IsArray reports whether type of the original struct field named name is slice.
func (g *Getter) IsArray(name string) bool {
- _, ok := g.getSafelyKindly(name, reflect.Array)
+ _, ok := g.getFieldKindly(name, reflect.Array)
return ok
}
@@ -597,7 +597,7 @@ func (g *Getter) IsArray(name string) bool {
// 2nd return value will be false if the original struct does not have a "name" field.
// 2nd return value will be false if type of the original struct "name" field is not struct or struct pointer.
func (g *Getter) GetGetter(name string) (*Getter, bool) {
- gf, ok := g.getSafelyKindly(name, reflect.Struct)
+ gf, ok := g.getFieldKindly(name, reflect.Struct)
if !ok {
return nil, false
}
@@ -608,7 +608,7 @@ func (g *Getter) GetGetter(name string) (*Getter, bool) {
// MapGet returns the interface slice of mapped values of the original struct field named name.
func (g *Getter) MapGet(name string, f func(int, *Getter) (interface{}, error)) ([]interface{}, error) {
- gf, ok := g.getSafelyKindly(name, reflect.Slice)
+ gf, ok := g.getFieldKindly(name, reflect.Slice)
if !ok {
return nil, fmt.Errorf("field %s does not exist or is not slice type", name)
}
diff --git a/go.mod b/go.mod
index cdd8982a..96bec9bf 100644
--- a/go.mod
+++ b/go.mod
@@ -4,15 +4,20 @@ go 1.19
require (
github.com/google/go-cmp v0.5.8
+ github.com/hashicorp/hcl/v2 v2.13.0
github.com/iancoleman/strcase v0.2.0
github.com/spf13/viper v1.12.0
+ github.com/zclconf/go-cty v1.10.0
gopkg.in/yaml.v3 v3.0.1
)
require (
+ github.com/agext/levenshtein v1.2.3 // indirect
+ github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/magiconair/properties v1.8.6 // indirect
+ github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.2 // indirect
diff --git a/go.sum b/go.sum
index 14890866..a817de12 100644
--- a/go.sum
+++ b/go.sum
@@ -38,6 +38,10 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
+github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
+github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
+github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
@@ -61,6 +65,7 @@ github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmV
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -121,6 +126,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc=
+github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0=
github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0=
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
@@ -134,8 +141,11 @@ github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4=
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
+github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
+github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
@@ -149,6 +159,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
+github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw=
github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
@@ -168,10 +179,14 @@ github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs=
github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo=
+github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
+github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0=
+github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@@ -312,6 +327,7 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
diff --git a/version.go b/version.go
index a82109a7..cac46c43 100644
--- a/version.go
+++ b/version.go
@@ -1,4 +1,4 @@
package structil
// VERSION says my version number
-const VERSION = "0.9.1"
+const VERSION = "0.10.0"
diff --git a/version_test.go b/version_test.go
index 9e3b287f..3dbfb1ae 100644
--- a/version_test.go
+++ b/version_test.go
@@ -7,7 +7,7 @@ import (
)
func TestVersion(t *testing.T) {
- exp := "0.9.1"
+ exp := "0.10.0"
if VERSION != exp {
t.Errorf("expected: %#v, but actual: %#v", exp, VERSION)