mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[feature] Add support for profile fields (#1483)
* Add go-playground/form pkg * [feature] Add support for profile fields * Add field attributes test * Validate profile fields form * Add profile field validation tests * Add Field Attributes definition to swagger --------- Co-authored-by: tobi <31960611+tsmethurst@users.noreply.github.com>
This commit is contained in:
748
vendor/github.com/go-playground/form/v4/decoder.go
generated
vendored
Normal file
748
vendor/github.com/go-playground/form/v4/decoder.go
generated
vendored
Normal file
@ -0,0 +1,748 @@
|
||||
package form
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
errArraySize = "Array size of '%d' is larger than the maximum currently set on the decoder of '%d'. To increase this limit please see, SetMaxArraySize(size uint)"
|
||||
errMissingStartBracket = "Invalid formatting for key '%s' missing '[' bracket"
|
||||
errMissingEndBracket = "Invalid formatting for key '%s' missing ']' bracket"
|
||||
)
|
||||
|
||||
type decoder struct {
|
||||
d *Decoder
|
||||
errs DecodeErrors
|
||||
dm dataMap
|
||||
values url.Values
|
||||
maxKeyLen int
|
||||
namespace []byte
|
||||
}
|
||||
|
||||
func (d *decoder) setError(namespace []byte, err error) {
|
||||
if d.errs == nil {
|
||||
d.errs = make(DecodeErrors)
|
||||
}
|
||||
d.errs[string(namespace)] = err
|
||||
}
|
||||
|
||||
func (d *decoder) findAlias(ns string) *recursiveData {
|
||||
for i := 0; i < len(d.dm); i++ {
|
||||
if d.dm[i].alias == ns {
|
||||
return d.dm[i]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *decoder) parseMapData() {
|
||||
// already parsed
|
||||
if len(d.dm) > 0 {
|
||||
return
|
||||
}
|
||||
|
||||
d.maxKeyLen = 0
|
||||
d.dm = d.dm[0:0]
|
||||
|
||||
var i int
|
||||
var idx int
|
||||
var l int
|
||||
var insideBracket bool
|
||||
var rd *recursiveData
|
||||
var isNum bool
|
||||
|
||||
for k := range d.values {
|
||||
|
||||
if len(k) > d.maxKeyLen {
|
||||
d.maxKeyLen = len(k)
|
||||
}
|
||||
|
||||
for i = 0; i < len(k); i++ {
|
||||
|
||||
switch k[i] {
|
||||
case '[':
|
||||
idx = i
|
||||
insideBracket = true
|
||||
isNum = true
|
||||
case ']':
|
||||
|
||||
if !insideBracket {
|
||||
log.Panicf(errMissingStartBracket, k)
|
||||
}
|
||||
|
||||
if rd = d.findAlias(k[:idx]); rd == nil {
|
||||
|
||||
l = len(d.dm) + 1
|
||||
|
||||
if l > cap(d.dm) {
|
||||
dm := make(dataMap, l)
|
||||
copy(dm, d.dm)
|
||||
rd = new(recursiveData)
|
||||
dm[len(d.dm)] = rd
|
||||
d.dm = dm
|
||||
} else {
|
||||
l = len(d.dm)
|
||||
d.dm = d.dm[:l+1]
|
||||
rd = d.dm[l]
|
||||
rd.sliceLen = 0
|
||||
rd.keys = rd.keys[0:0]
|
||||
}
|
||||
|
||||
rd.alias = k[:idx]
|
||||
}
|
||||
|
||||
// is map + key
|
||||
ke := key{
|
||||
ivalue: -1,
|
||||
value: k[idx+1 : i],
|
||||
searchValue: k[idx : i+1],
|
||||
}
|
||||
|
||||
// is key is number, most likely array key, keep track of just in case an array/slice.
|
||||
if isNum {
|
||||
|
||||
// no need to check for error, it will always pass
|
||||
// as we have done the checking to ensure
|
||||
// the value is a number ahead of time.
|
||||
ke.ivalue, _ = strconv.Atoi(ke.value)
|
||||
|
||||
if ke.ivalue > rd.sliceLen {
|
||||
rd.sliceLen = ke.ivalue
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
rd.keys = append(rd.keys, ke)
|
||||
|
||||
insideBracket = false
|
||||
default:
|
||||
// checking if not a number, 0-9 is 48-57 in byte, see for yourself fmt.Println('0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
|
||||
if insideBracket && (k[i] > 57 || k[i] < 48) {
|
||||
isNum = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if still inside bracket, that means no ending bracket was ever specified
|
||||
if insideBracket {
|
||||
log.Panicf(errMissingEndBracket, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (d *decoder) traverseStruct(v reflect.Value, typ reflect.Type, namespace []byte) (set bool) {
|
||||
|
||||
l := len(namespace)
|
||||
first := l == 0
|
||||
|
||||
// anonymous structs will still work for caching as the whole definition is stored
|
||||
// including tags
|
||||
s, ok := d.d.structCache.Get(typ)
|
||||
if !ok {
|
||||
s = d.d.structCache.parseStruct(d.d.mode, v, typ, d.d.tagName)
|
||||
}
|
||||
|
||||
for _, f := range s.fields {
|
||||
namespace = namespace[:l]
|
||||
|
||||
if f.isAnonymous {
|
||||
if d.setFieldByType(v.Field(f.idx), namespace, 0) {
|
||||
set = true
|
||||
}
|
||||
}
|
||||
|
||||
if first {
|
||||
namespace = append(namespace, f.name...)
|
||||
} else {
|
||||
namespace = append(namespace, d.d.namespacePrefix...)
|
||||
namespace = append(namespace, f.name...)
|
||||
namespace = append(namespace, d.d.namespaceSuffix...)
|
||||
}
|
||||
|
||||
if d.setFieldByType(v.Field(f.idx), namespace, 0) {
|
||||
set = true
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (d *decoder) setFieldByType(current reflect.Value, namespace []byte, idx int) (set bool) {
|
||||
|
||||
var err error
|
||||
v, kind := ExtractType(current)
|
||||
|
||||
arr, ok := d.values[string(namespace)]
|
||||
|
||||
if d.d.customTypeFuncs != nil {
|
||||
|
||||
if ok {
|
||||
if cf, ok := d.d.customTypeFuncs[v.Type()]; ok {
|
||||
val, err := cf(arr[idx:])
|
||||
if err != nil {
|
||||
d.setError(namespace, err)
|
||||
return
|
||||
}
|
||||
|
||||
v.Set(reflect.ValueOf(val))
|
||||
set = true
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
switch kind {
|
||||
case reflect.Interface:
|
||||
if !ok || idx == len(arr) {
|
||||
return
|
||||
}
|
||||
v.Set(reflect.ValueOf(arr[idx]))
|
||||
set = true
|
||||
|
||||
case reflect.Ptr:
|
||||
newVal := reflect.New(v.Type().Elem())
|
||||
if set = d.setFieldByType(newVal.Elem(), namespace, idx); set {
|
||||
v.Set(newVal)
|
||||
}
|
||||
|
||||
case reflect.String:
|
||||
if !ok || idx == len(arr) {
|
||||
return
|
||||
}
|
||||
v.SetString(arr[idx])
|
||||
set = true
|
||||
|
||||
case reflect.Uint, reflect.Uint64:
|
||||
if !ok || idx == len(arr) || len(arr[idx]) == 0 {
|
||||
return
|
||||
}
|
||||
var u64 uint64
|
||||
if u64, err = strconv.ParseUint(arr[idx], 10, 64); err != nil {
|
||||
d.setError(namespace, fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
|
||||
return
|
||||
}
|
||||
v.SetUint(u64)
|
||||
set = true
|
||||
|
||||
case reflect.Uint8:
|
||||
if !ok || idx == len(arr) || len(arr[idx]) == 0 {
|
||||
return
|
||||
}
|
||||
var u64 uint64
|
||||
if u64, err = strconv.ParseUint(arr[idx], 10, 8); err != nil {
|
||||
d.setError(namespace, fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
|
||||
return
|
||||
}
|
||||
v.SetUint(u64)
|
||||
set = true
|
||||
|
||||
case reflect.Uint16:
|
||||
if !ok || idx == len(arr) || len(arr[idx]) == 0 {
|
||||
return
|
||||
}
|
||||
var u64 uint64
|
||||
if u64, err = strconv.ParseUint(arr[idx], 10, 16); err != nil {
|
||||
d.setError(namespace, fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
|
||||
return
|
||||
}
|
||||
v.SetUint(u64)
|
||||
set = true
|
||||
|
||||
case reflect.Uint32:
|
||||
if !ok || idx == len(arr) || len(arr[idx]) == 0 {
|
||||
return
|
||||
}
|
||||
var u64 uint64
|
||||
if u64, err = strconv.ParseUint(arr[idx], 10, 32); err != nil {
|
||||
d.setError(namespace, fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
|
||||
return
|
||||
}
|
||||
v.SetUint(u64)
|
||||
set = true
|
||||
|
||||
case reflect.Int, reflect.Int64:
|
||||
if !ok || idx == len(arr) || len(arr[idx]) == 0 {
|
||||
return
|
||||
}
|
||||
var i64 int64
|
||||
if i64, err = strconv.ParseInt(arr[idx], 10, 64); err != nil {
|
||||
d.setError(namespace, fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
|
||||
return
|
||||
}
|
||||
v.SetInt(i64)
|
||||
set = true
|
||||
|
||||
case reflect.Int8:
|
||||
if !ok || idx == len(arr) || len(arr[idx]) == 0 {
|
||||
return
|
||||
}
|
||||
var i64 int64
|
||||
if i64, err = strconv.ParseInt(arr[idx], 10, 8); err != nil {
|
||||
d.setError(namespace, fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
|
||||
return
|
||||
}
|
||||
v.SetInt(i64)
|
||||
set = true
|
||||
|
||||
case reflect.Int16:
|
||||
if !ok || idx == len(arr) || len(arr[idx]) == 0 {
|
||||
return
|
||||
}
|
||||
var i64 int64
|
||||
if i64, err = strconv.ParseInt(arr[idx], 10, 16); err != nil {
|
||||
d.setError(namespace, fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
|
||||
return
|
||||
}
|
||||
v.SetInt(i64)
|
||||
set = true
|
||||
|
||||
case reflect.Int32:
|
||||
if !ok || idx == len(arr) || len(arr[idx]) == 0 {
|
||||
return
|
||||
}
|
||||
var i64 int64
|
||||
if i64, err = strconv.ParseInt(arr[idx], 10, 32); err != nil {
|
||||
d.setError(namespace, fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
|
||||
return
|
||||
}
|
||||
v.SetInt(i64)
|
||||
set = true
|
||||
|
||||
case reflect.Float32:
|
||||
if !ok || idx == len(arr) || len(arr[idx]) == 0 {
|
||||
return
|
||||
}
|
||||
var f float64
|
||||
if f, err = strconv.ParseFloat(arr[idx], 32); err != nil {
|
||||
d.setError(namespace, fmt.Errorf("Invalid Float Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
|
||||
return
|
||||
}
|
||||
v.SetFloat(f)
|
||||
set = true
|
||||
|
||||
case reflect.Float64:
|
||||
if !ok || idx == len(arr) || len(arr[idx]) == 0 {
|
||||
return
|
||||
}
|
||||
var f float64
|
||||
if f, err = strconv.ParseFloat(arr[idx], 64); err != nil {
|
||||
d.setError(namespace, fmt.Errorf("Invalid Float Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
|
||||
return
|
||||
}
|
||||
v.SetFloat(f)
|
||||
set = true
|
||||
|
||||
case reflect.Bool:
|
||||
if !ok || idx == len(arr) {
|
||||
return
|
||||
}
|
||||
var b bool
|
||||
if b, err = parseBool(arr[idx]); err != nil {
|
||||
d.setError(namespace, fmt.Errorf("Invalid Boolean Value '%s' Type '%v' Namespace '%s'", arr[idx], v.Type(), string(namespace)))
|
||||
return
|
||||
}
|
||||
v.SetBool(b)
|
||||
set = true
|
||||
|
||||
case reflect.Slice:
|
||||
d.parseMapData()
|
||||
// slice elements could be mixed eg. number and non-numbers Value[0]=[]string{"10"} and Value=[]string{"10","20"}
|
||||
|
||||
if ok && len(arr) > 0 {
|
||||
var varr reflect.Value
|
||||
|
||||
var ol int
|
||||
l := len(arr)
|
||||
|
||||
if v.IsNil() {
|
||||
varr = reflect.MakeSlice(v.Type(), len(arr), len(arr))
|
||||
} else {
|
||||
|
||||
ol = v.Len()
|
||||
l += ol
|
||||
|
||||
if v.Cap() <= l {
|
||||
varr = reflect.MakeSlice(v.Type(), l, l)
|
||||
} else {
|
||||
// preserve predefined capacity, possibly for reuse after decoding
|
||||
varr = reflect.MakeSlice(v.Type(), l, v.Cap())
|
||||
}
|
||||
reflect.Copy(varr, v)
|
||||
}
|
||||
|
||||
for i := ol; i < l; i++ {
|
||||
newVal := reflect.New(v.Type().Elem()).Elem()
|
||||
|
||||
if d.setFieldByType(newVal, namespace, i-ol) {
|
||||
set = true
|
||||
varr.Index(i).Set(newVal)
|
||||
}
|
||||
}
|
||||
|
||||
v.Set(varr)
|
||||
}
|
||||
|
||||
// maybe it's an numbered array i.e. Phone[0].Number
|
||||
if rd := d.findAlias(string(namespace)); rd != nil {
|
||||
|
||||
var varr reflect.Value
|
||||
var kv key
|
||||
|
||||
sl := rd.sliceLen + 1
|
||||
|
||||
// checking below for maxArraySize, but if array exists and already
|
||||
// has sufficient capacity allocated then we do not check as the code
|
||||
// obviously allows a capacity greater than the maxArraySize.
|
||||
|
||||
if v.IsNil() {
|
||||
|
||||
if sl > d.d.maxArraySize {
|
||||
d.setError(namespace, fmt.Errorf(errArraySize, sl, d.d.maxArraySize))
|
||||
return
|
||||
}
|
||||
|
||||
varr = reflect.MakeSlice(v.Type(), sl, sl)
|
||||
|
||||
} else if v.Len() < sl {
|
||||
|
||||
if v.Cap() <= sl {
|
||||
|
||||
if sl > d.d.maxArraySize {
|
||||
d.setError(namespace, fmt.Errorf(errArraySize, sl, d.d.maxArraySize))
|
||||
return
|
||||
}
|
||||
|
||||
varr = reflect.MakeSlice(v.Type(), sl, sl)
|
||||
} else {
|
||||
varr = reflect.MakeSlice(v.Type(), sl, v.Cap())
|
||||
}
|
||||
|
||||
reflect.Copy(varr, v)
|
||||
|
||||
} else {
|
||||
varr = v
|
||||
}
|
||||
|
||||
for i := 0; i < len(rd.keys); i++ {
|
||||
|
||||
kv = rd.keys[i]
|
||||
newVal := reflect.New(varr.Type().Elem()).Elem()
|
||||
|
||||
if kv.ivalue == -1 {
|
||||
d.setError(namespace, fmt.Errorf("invalid slice index '%s'", kv.value))
|
||||
continue
|
||||
}
|
||||
|
||||
if d.setFieldByType(newVal, append(namespace, kv.searchValue...), 0) {
|
||||
set = true
|
||||
varr.Index(kv.ivalue).Set(newVal)
|
||||
}
|
||||
}
|
||||
|
||||
if !set {
|
||||
return
|
||||
}
|
||||
|
||||
v.Set(varr)
|
||||
}
|
||||
|
||||
case reflect.Array:
|
||||
d.parseMapData()
|
||||
|
||||
// array elements could be mixed eg. number and non-numbers Value[0]=[]string{"10"} and Value=[]string{"10","20"}
|
||||
|
||||
if ok && len(arr) > 0 {
|
||||
var varr reflect.Value
|
||||
l := len(arr)
|
||||
overCapacity := v.Len() < l
|
||||
if overCapacity {
|
||||
// more values than array capacity, ignore values over capacity as it's possible some would just want
|
||||
// to grab the first x number of elements; in the future strict mode logic should return an error
|
||||
fmt.Println("warning number of post form array values is larger than array capacity, ignoring overflow values")
|
||||
}
|
||||
varr = reflect.Indirect(reflect.New(reflect.ArrayOf(v.Len(), v.Type().Elem())))
|
||||
reflect.Copy(varr, v)
|
||||
|
||||
if v.Len() < len(arr) {
|
||||
l = v.Len()
|
||||
}
|
||||
for i := 0; i < l; i++ {
|
||||
newVal := reflect.New(v.Type().Elem()).Elem()
|
||||
|
||||
if d.setFieldByType(newVal, namespace, i) {
|
||||
set = true
|
||||
varr.Index(i).Set(newVal)
|
||||
}
|
||||
}
|
||||
v.Set(varr)
|
||||
}
|
||||
|
||||
// maybe it's an numbered array i.e. Phone[0].Number
|
||||
if rd := d.findAlias(string(namespace)); rd != nil {
|
||||
var varr reflect.Value
|
||||
var kv key
|
||||
|
||||
overCapacity := rd.sliceLen >= v.Len()
|
||||
if overCapacity {
|
||||
// more values than array capacity, ignore values over capacity as it's possible some would just want
|
||||
// to grab the first x number of elements; in the future strict mode logic should return an error
|
||||
fmt.Println("warning number of post form array values is larger than array capacity, ignoring overflow values")
|
||||
}
|
||||
varr = reflect.Indirect(reflect.New(reflect.ArrayOf(v.Len(), v.Type().Elem())))
|
||||
reflect.Copy(varr, v)
|
||||
|
||||
for i := 0; i < len(rd.keys); i++ {
|
||||
kv = rd.keys[i]
|
||||
if kv.ivalue >= v.Len() {
|
||||
continue
|
||||
}
|
||||
newVal := reflect.New(varr.Type().Elem()).Elem()
|
||||
|
||||
if kv.ivalue == -1 {
|
||||
d.setError(namespace, fmt.Errorf("invalid array index '%s'", kv.value))
|
||||
continue
|
||||
}
|
||||
|
||||
if d.setFieldByType(newVal, append(namespace, kv.searchValue...), 0) {
|
||||
set = true
|
||||
varr.Index(kv.ivalue).Set(newVal)
|
||||
}
|
||||
}
|
||||
|
||||
if !set {
|
||||
return
|
||||
}
|
||||
v.Set(varr)
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
var rd *recursiveData
|
||||
|
||||
d.parseMapData()
|
||||
|
||||
// no natural map support so skip directly to dm lookup
|
||||
if rd = d.findAlias(string(namespace)); rd == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var existing bool
|
||||
var kv key
|
||||
var mp reflect.Value
|
||||
var mk reflect.Value
|
||||
|
||||
typ := v.Type()
|
||||
|
||||
if v.IsNil() {
|
||||
mp = reflect.MakeMap(typ)
|
||||
} else {
|
||||
existing = true
|
||||
mp = v
|
||||
}
|
||||
|
||||
for i := 0; i < len(rd.keys); i++ {
|
||||
newVal := reflect.New(typ.Elem()).Elem()
|
||||
mk = reflect.New(typ.Key()).Elem()
|
||||
kv = rd.keys[i]
|
||||
|
||||
if err := d.getMapKey(kv.value, mk, namespace); err != nil {
|
||||
d.setError(namespace, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if d.setFieldByType(newVal, append(namespace, kv.searchValue...), 0) {
|
||||
set = true
|
||||
mp.SetMapIndex(mk, newVal)
|
||||
}
|
||||
}
|
||||
|
||||
if !set || existing {
|
||||
return
|
||||
}
|
||||
|
||||
v.Set(mp)
|
||||
|
||||
case reflect.Struct:
|
||||
typ := v.Type()
|
||||
|
||||
// if we get here then no custom time function declared so use RFC3339 by default
|
||||
if typ == timeType {
|
||||
|
||||
if !ok || len(arr[idx]) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
t, err := time.Parse(time.RFC3339, arr[idx])
|
||||
if err != nil {
|
||||
d.setError(namespace, err)
|
||||
}
|
||||
|
||||
v.Set(reflect.ValueOf(t))
|
||||
set = true
|
||||
return
|
||||
}
|
||||
|
||||
d.parseMapData()
|
||||
|
||||
// we must be recursing infinitly...but that's ok we caught it on the very first overun.
|
||||
if len(namespace) > d.maxKeyLen {
|
||||
return
|
||||
}
|
||||
|
||||
set = d.traverseStruct(v, typ, namespace)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *decoder) getMapKey(key string, current reflect.Value, namespace []byte) (err error) {
|
||||
|
||||
v, kind := ExtractType(current)
|
||||
|
||||
if d.d.customTypeFuncs != nil {
|
||||
if cf, ok := d.d.customTypeFuncs[v.Type()]; ok {
|
||||
|
||||
val, er := cf([]string{key})
|
||||
if er != nil {
|
||||
err = er
|
||||
return
|
||||
}
|
||||
|
||||
v.Set(reflect.ValueOf(val))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
switch kind {
|
||||
case reflect.Interface:
|
||||
// If interface would have been set on the struct before decoding,
|
||||
// say to a struct value we would not get here but kind would be struct.
|
||||
v.Set(reflect.ValueOf(key))
|
||||
return
|
||||
case reflect.Ptr:
|
||||
newVal := reflect.New(v.Type().Elem())
|
||||
if err = d.getMapKey(key, newVal.Elem(), namespace); err == nil {
|
||||
v.Set(newVal)
|
||||
}
|
||||
|
||||
case reflect.String:
|
||||
v.SetString(key)
|
||||
|
||||
case reflect.Uint, reflect.Uint64:
|
||||
|
||||
u64, e := strconv.ParseUint(key, 10, 64)
|
||||
if e != nil {
|
||||
err = fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
|
||||
return
|
||||
}
|
||||
|
||||
v.SetUint(u64)
|
||||
|
||||
case reflect.Uint8:
|
||||
|
||||
u64, e := strconv.ParseUint(key, 10, 8)
|
||||
if e != nil {
|
||||
err = fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
|
||||
return
|
||||
}
|
||||
|
||||
v.SetUint(u64)
|
||||
|
||||
case reflect.Uint16:
|
||||
|
||||
u64, e := strconv.ParseUint(key, 10, 16)
|
||||
if e != nil {
|
||||
err = fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
|
||||
return
|
||||
}
|
||||
|
||||
v.SetUint(u64)
|
||||
|
||||
case reflect.Uint32:
|
||||
|
||||
u64, e := strconv.ParseUint(key, 10, 32)
|
||||
if e != nil {
|
||||
err = fmt.Errorf("Invalid Unsigned Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
|
||||
return
|
||||
}
|
||||
|
||||
v.SetUint(u64)
|
||||
|
||||
case reflect.Int, reflect.Int64:
|
||||
|
||||
i64, e := strconv.ParseInt(key, 10, 64)
|
||||
if e != nil {
|
||||
err = fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
|
||||
return
|
||||
}
|
||||
|
||||
v.SetInt(i64)
|
||||
|
||||
case reflect.Int8:
|
||||
|
||||
i64, e := strconv.ParseInt(key, 10, 8)
|
||||
if e != nil {
|
||||
err = fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
|
||||
return
|
||||
}
|
||||
|
||||
v.SetInt(i64)
|
||||
|
||||
case reflect.Int16:
|
||||
|
||||
i64, e := strconv.ParseInt(key, 10, 16)
|
||||
if e != nil {
|
||||
err = fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
|
||||
return
|
||||
}
|
||||
|
||||
v.SetInt(i64)
|
||||
|
||||
case reflect.Int32:
|
||||
|
||||
i64, e := strconv.ParseInt(key, 10, 32)
|
||||
if e != nil {
|
||||
err = fmt.Errorf("Invalid Integer Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
|
||||
return
|
||||
}
|
||||
|
||||
v.SetInt(i64)
|
||||
|
||||
case reflect.Float32:
|
||||
|
||||
f, e := strconv.ParseFloat(key, 32)
|
||||
if e != nil {
|
||||
err = fmt.Errorf("Invalid Float Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
|
||||
return
|
||||
}
|
||||
|
||||
v.SetFloat(f)
|
||||
|
||||
case reflect.Float64:
|
||||
|
||||
f, e := strconv.ParseFloat(key, 64)
|
||||
if e != nil {
|
||||
err = fmt.Errorf("Invalid Float Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
|
||||
return
|
||||
}
|
||||
|
||||
v.SetFloat(f)
|
||||
|
||||
case reflect.Bool:
|
||||
|
||||
b, e := parseBool(key)
|
||||
if e != nil {
|
||||
err = fmt.Errorf("Invalid Boolean Value '%s' Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
|
||||
return
|
||||
}
|
||||
|
||||
v.SetBool(b)
|
||||
|
||||
default:
|
||||
err = fmt.Errorf("Unsupported Map Key '%s', Type '%v' Namespace '%s'", key, v.Type(), string(namespace))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
Reference in New Issue
Block a user