Improved default tag for durations (#464)
This commit is contained in:
+14
@@ -830,7 +830,21 @@ func (d *Decoder) valueFromTree(mtype reflect.Type, tval *Tree, mval1 *reflect.V
|
|||||||
case reflect.Int32:
|
case reflect.Int32:
|
||||||
val, err = strconv.ParseInt(opts.defaultValue, 10, 32)
|
val, err = strconv.ParseInt(opts.defaultValue, 10, 32)
|
||||||
case reflect.Int64:
|
case reflect.Int64:
|
||||||
|
// Check if the provided number has a non-numeric extension.
|
||||||
|
var hasExtension bool
|
||||||
|
if len(opts.defaultValue) > 0 {
|
||||||
|
lastChar := opts.defaultValue[len(opts.defaultValue)-1]
|
||||||
|
if lastChar < '0' || lastChar > '9' {
|
||||||
|
hasExtension = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If the value is a time.Duration with extension, parse as duration.
|
||||||
|
// If the value is an int64 or a time.Duration without extension, parse as number.
|
||||||
|
if hasExtension && mvalf.Type().String() == "time.Duration" {
|
||||||
|
val, err = time.ParseDuration(opts.defaultValue)
|
||||||
|
} else {
|
||||||
val, err = strconv.ParseInt(opts.defaultValue, 10, 64)
|
val, err = strconv.ParseInt(opts.defaultValue, 10, 64)
|
||||||
|
}
|
||||||
case reflect.Float32:
|
case reflect.Float32:
|
||||||
val, err = strconv.ParseFloat(opts.defaultValue, 32)
|
val, err = strconv.ParseFloat(opts.defaultValue, 32)
|
||||||
case reflect.Float64:
|
case reflect.Float64:
|
||||||
|
|||||||
@@ -2300,6 +2300,8 @@ func TestUnmarshalDefault(t *testing.T) {
|
|||||||
Int64Field int64 `default:"-64"`
|
Int64Field int64 `default:"-64"`
|
||||||
Float32Field float32 `default:"32.1"`
|
Float32Field float32 `default:"32.1"`
|
||||||
Float64Field float64 `default:"64.1"`
|
Float64Field float64 `default:"64.1"`
|
||||||
|
DurationField time.Duration `default:"120ms"`
|
||||||
|
DurationField2 time.Duration `default:"120000000"`
|
||||||
NonEmbeddedStruct struct {
|
NonEmbeddedStruct struct {
|
||||||
StringField string `default:"b"`
|
StringField string `default:"b"`
|
||||||
}
|
}
|
||||||
@@ -2353,6 +2355,12 @@ func TestUnmarshalDefault(t *testing.T) {
|
|||||||
if doc.Float64Field != 64.1 {
|
if doc.Float64Field != 64.1 {
|
||||||
t.Errorf("Float64Field should be 64.1, not %f", doc.Float64Field)
|
t.Errorf("Float64Field should be 64.1, not %f", doc.Float64Field)
|
||||||
}
|
}
|
||||||
|
if doc.DurationField != 120*time.Millisecond {
|
||||||
|
t.Errorf("DurationField should be 120ms, not %s", doc.DurationField.String())
|
||||||
|
}
|
||||||
|
if doc.DurationField2 != 120*time.Millisecond {
|
||||||
|
t.Errorf("DurationField2 should be 120000000, not %d", doc.DurationField2)
|
||||||
|
}
|
||||||
if doc.NonEmbeddedStruct.StringField != "b" {
|
if doc.NonEmbeddedStruct.StringField != "b" {
|
||||||
t.Errorf("StringField should be \"b\", not %s", doc.NonEmbeddedStruct.StringField)
|
t.Errorf("StringField should be \"b\", not %s", doc.NonEmbeddedStruct.StringField)
|
||||||
}
|
}
|
||||||
@@ -2408,6 +2416,17 @@ func TestUnmarshalDefaultFailureFloat64(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalDefaultFailureDuration(t *testing.T) {
|
||||||
|
var doc struct {
|
||||||
|
Field time.Duration `default:"blah"`
|
||||||
|
}
|
||||||
|
|
||||||
|
err := Unmarshal([]byte(``), &doc)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("should error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestUnmarshalDefaultFailureUnsupported(t *testing.T) {
|
func TestUnmarshalDefaultFailureUnsupported(t *testing.T) {
|
||||||
var doc struct {
|
var doc struct {
|
||||||
Field struct{} `default:"blah"`
|
Field struct{} `default:"blah"`
|
||||||
|
|||||||
Reference in New Issue
Block a user