diff --git a/marshal.go b/marshal.go index 717f15c..c688532 100644 --- a/marshal.go +++ b/marshal.go @@ -731,32 +731,42 @@ func (d *Decoder) valueFromTree(mtype reflect.Type, tval *Tree, mval1 *reflect.V var val interface{} var err error switch mvalf.Kind() { - case reflect.Bool: - val, err = strconv.ParseBool(opts.defaultValue) - if err != nil { - return mval.Field(i), err - } - case reflect.Int: - val, err = strconv.Atoi(opts.defaultValue) - if err != nil { - return mval.Field(i), err - } case reflect.String: val = opts.defaultValue + case reflect.Bool: + val, err = strconv.ParseBool(opts.defaultValue) + case reflect.Uint: + val, err = strconv.ParseUint(opts.defaultValue, 10, 0) + case reflect.Uint8: + val, err = strconv.ParseUint(opts.defaultValue, 10, 8) + case reflect.Uint16: + val, err = strconv.ParseUint(opts.defaultValue, 10, 16) + case reflect.Uint32: + val, err = strconv.ParseUint(opts.defaultValue, 10, 32) + case reflect.Uint64: + val, err = strconv.ParseUint(opts.defaultValue, 10, 64) + case reflect.Int: + val, err = strconv.ParseInt(opts.defaultValue, 10, 0) + case reflect.Int8: + val, err = strconv.ParseInt(opts.defaultValue, 10, 8) + case reflect.Int16: + val, err = strconv.ParseInt(opts.defaultValue, 10, 16) + case reflect.Int32: + val, err = strconv.ParseInt(opts.defaultValue, 10, 32) case reflect.Int64: val, err = strconv.ParseInt(opts.defaultValue, 10, 64) - if err != nil { - return mval.Field(i), err - } + case reflect.Float32: + val, err = strconv.ParseFloat(opts.defaultValue, 32) case reflect.Float64: val, err = strconv.ParseFloat(opts.defaultValue, 64) - if err != nil { - return mval.Field(i), err - } default: - return mval.Field(i), fmt.Errorf("unsupported field type for default option") + return mvalf, fmt.Errorf("unsupported field type for default option") } - mval.Field(i).Set(reflect.ValueOf(val)) + + if err != nil { + return mvalf, err + } + mvalf.Set(reflect.ValueOf(val).Convert(mvalf.Type())) } // save the old behavior above and try to check structs diff --git a/marshal_test.go b/marshal_test.go index b5bb084..cb9f7ee 100644 --- a/marshal_test.go +++ b/marshal_test.go @@ -2054,16 +2054,28 @@ func TestUnmarshalDefault(t *testing.T) { StringField string `default:"c"` } + type aliasUint uint + var doc struct { StringField string `default:"a"` BoolField bool `default:"true"` - IntField int `default:"1"` - Int64Field int64 `default:"2"` - Float64Field float64 `default:"3.1"` + UintField uint `default:"1"` + Uint8Field uint8 `default:"8"` + Uint16Field uint16 `default:"16"` + Uint32Field uint32 `default:"32"` + Uint64Field uint64 `default:"64"` + IntField int `default:"-1"` + Int8Field int8 `default:"-8"` + Int16Field int16 `default:"-16"` + Int32Field int32 `default:"-32"` + Int64Field int64 `default:"-64"` + Float32Field float32 `default:"32.1"` + Float64Field float64 `default:"64.1"` NonEmbeddedStruct struct { StringField string `default:"b"` } EmbeddedStruct + AliasUintField aliasUint `default:"1000"` } err := Unmarshal([]byte(``), &doc) @@ -2076,14 +2088,41 @@ func TestUnmarshalDefault(t *testing.T) { if doc.StringField != "a" { t.Errorf("StringField should be \"a\", not %s", doc.StringField) } - if doc.IntField != 1 { - t.Errorf("IntField should be 1, not %d", doc.IntField) + if doc.UintField != 1 { + t.Errorf("UintField should be 1, not %d", doc.UintField) } - if doc.Int64Field != 2 { - t.Errorf("Int64Field should be 2, not %d", doc.Int64Field) + if doc.Uint8Field != 8 { + t.Errorf("Uint8Field should be 8, not %d", doc.Uint8Field) } - if doc.Float64Field != 3.1 { - t.Errorf("Float64Field should be 3.1, not %f", doc.Float64Field) + if doc.Uint16Field != 16 { + t.Errorf("Uint16Field should be 16, not %d", doc.Uint16Field) + } + if doc.Uint32Field != 32 { + t.Errorf("Uint32Field should be 32, not %d", doc.Uint32Field) + } + if doc.Uint64Field != 64 { + t.Errorf("Uint64Field should be 64, not %d", doc.Uint64Field) + } + if doc.IntField != -1 { + t.Errorf("IntField should be -1, not %d", doc.IntField) + } + if doc.Int8Field != -8 { + t.Errorf("Int8Field should be -8, not %d", doc.Int8Field) + } + if doc.Int16Field != -16 { + t.Errorf("Int16Field should be -16, not %d", doc.Int16Field) + } + if doc.Int32Field != -32 { + t.Errorf("Int32Field should be -32, not %d", doc.Int32Field) + } + if doc.Int64Field != -64 { + t.Errorf("Int64Field should be -64, not %d", doc.Int64Field) + } + if doc.Float32Field != 32.1 { + t.Errorf("Float32Field should be 32.1, not %f", doc.Float32Field) + } + if doc.Float64Field != 64.1 { + t.Errorf("Float64Field should be 64.1, not %f", doc.Float64Field) } if doc.NonEmbeddedStruct.StringField != "b" { t.Errorf("StringField should be \"b\", not %s", doc.NonEmbeddedStruct.StringField) @@ -2091,6 +2130,9 @@ func TestUnmarshalDefault(t *testing.T) { if doc.EmbeddedStruct.StringField != "c" { t.Errorf("StringField should be \"c\", not %s", doc.EmbeddedStruct.StringField) } + if doc.AliasUintField != 1000 { + t.Errorf("AliasUintField should be 1000, not %d", doc.AliasUintField) + } } func TestUnmarshalDefaultFailureBool(t *testing.T) {