logical/framework: adding a new duration type to convert to seconds

This commit is contained in:
Armon Dadgar 2015-06-17 15:56:26 -07:00
parent 5c75a6c5c7
commit 6b23b14773
5 changed files with 98 additions and 7 deletions

View file

@ -373,6 +373,8 @@ func (t FieldType) Zero() interface{} {
return false
case TypeMap:
return map[string]interface{}{}
case TypeDurationSecond:
return 0
default:
panic("unknown type: " + t.String())
}

View file

@ -508,6 +508,16 @@ func TestFieldSchemaDefaultOrZero(t *testing.T) {
&FieldSchema{Type: TypeString},
"",
},
"default duration set": {
&FieldSchema{Type: TypeDurationSecond, Default: 60},
60,
},
"default duration not set": {
&FieldSchema{Type: TypeDurationSecond},
0,
},
}
for name, tc := range cases {

View file

@ -2,6 +2,9 @@ package framework
import (
"fmt"
"strconv"
"strings"
"time"
"github.com/mitchellh/mapstructure"
)
@ -64,13 +67,7 @@ func (d *FieldData) GetOkErr(k string) (interface{}, bool, error) {
}
switch schema.Type {
case TypeBool:
fallthrough
case TypeInt:
fallthrough
case TypeMap:
fallthrough
case TypeString:
case TypeBool, TypeInt, TypeMap, TypeDurationSecond, TypeString:
return d.getPrimitive(k, schema)
default:
return nil, false,
@ -114,6 +111,38 @@ func (d *FieldData) getPrimitive(
}
return result, true, nil
case TypeDurationSecond:
var result int
switch inp := raw.(type) {
case int:
result = inp
case float32:
result = int(inp)
case float64:
result = int(inp)
case string:
// Look for a suffix otherwise its a plain second value
if strings.HasSuffix(inp, "s") || strings.HasSuffix(inp, "m") || strings.HasSuffix(inp, "h") {
dur, err := time.ParseDuration(inp)
if err != nil {
return nil, true, err
}
result = int(dur.Seconds())
} else {
// Plain integer
val, err := strconv.ParseInt(inp, 10, 64)
if err != nil {
return nil, true, err
}
result = int(val)
}
default:
return nil, false, fmt.Errorf("invalid input '%v'", raw)
}
return result, true, nil
default:
panic(fmt.Sprintf("Unknown type: %s", schema.Type))
}

View file

@ -91,6 +91,50 @@ func TestFieldDataGet(t *testing.T) {
"child": true,
},
},
"duration type, string value": {
map[string]*FieldSchema{
"foo": &FieldSchema{Type: TypeDurationSecond},
},
map[string]interface{}{
"foo": "42",
},
"foo",
42,
},
"duration type, string duration value": {
map[string]*FieldSchema{
"foo": &FieldSchema{Type: TypeDurationSecond},
},
map[string]interface{}{
"foo": "42m",
},
"foo",
2520,
},
"duration type, int value": {
map[string]*FieldSchema{
"foo": &FieldSchema{Type: TypeDurationSecond},
},
map[string]interface{}{
"foo": 42,
},
"foo",
42,
},
"duration type, float value": {
map[string]*FieldSchema{
"foo": &FieldSchema{Type: TypeDurationSecond},
},
map[string]interface{}{
"foo": 42.0,
},
"foo",
42,
},
}
for name, tc := range cases {

View file

@ -9,6 +9,10 @@ const (
TypeInt
TypeBool
TypeMap
// TypeDurationSecond represent as seconds, this can be either an
// integer or go duration format string (e.g. 24h)
TypeDurationSecond
)
func (t FieldType) String() string {
@ -21,6 +25,8 @@ func (t FieldType) String() string {
return "bool"
case TypeMap:
return "map"
case TypeDurationSecond:
return "duration (sec)"
default:
return "unknown type"
}