Skip to content

Commit 591552f

Browse files
committed
library, first version
0 parents  commit 591552f

File tree

2 files changed

+176
-0
lines changed

2 files changed

+176
-0
lines changed

defaults.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package defaults
2+
3+
import (
4+
"reflect"
5+
"strconv"
6+
)
7+
8+
type Field struct {
9+
Field reflect.StructField
10+
Value reflect.Value
11+
}
12+
13+
func SetDefaults(variable interface{}) {
14+
fields := getFields(variable)
15+
setDefaultValues(fields)
16+
}
17+
18+
func getFields(variable interface{}) []*Field {
19+
valueObject := reflect.ValueOf(variable).Elem()
20+
21+
return getFieldsFromValue(valueObject)
22+
}
23+
24+
func getFieldsFromValue(valueObject reflect.Value) []*Field {
25+
typeObject := valueObject.Type()
26+
27+
count := valueObject.NumField()
28+
results := make([]*Field, 0)
29+
for i := 0; i < count; i++ {
30+
value := valueObject.Field(i)
31+
field := typeObject.Field(i)
32+
33+
if value.CanSet() {
34+
results = append(results, &Field{
35+
Value: value,
36+
Field: field,
37+
})
38+
}
39+
}
40+
41+
return results
42+
}
43+
44+
func setDefaultValues(fields []*Field) {
45+
for _, field := range fields {
46+
setDefaultValue(field)
47+
}
48+
}
49+
50+
func setDefaultValue(field *Field) {
51+
defaultValue := field.Field.Tag.Get("default")
52+
53+
switch field.Value.Kind() {
54+
case reflect.Bool:
55+
setDefaultValueToBool(field, defaultValue)
56+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
57+
setDefaultValueToInt(field, defaultValue)
58+
case reflect.Float32, reflect.Float64:
59+
setDefaultValueToFloat(field, defaultValue)
60+
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
61+
setDefaultValueToUint(field, defaultValue)
62+
case reflect.Slice:
63+
setDefaultValueToSlice(field, defaultValue)
64+
case reflect.String:
65+
setDefaultValueToString(field, defaultValue)
66+
case reflect.Struct:
67+
setDefaultValueToStruct(field, defaultValue)
68+
}
69+
}
70+
71+
func setDefaultValueToBool(field *Field, defaultValue string) {
72+
value, _ := strconv.ParseBool(defaultValue)
73+
field.Value.SetBool(value)
74+
}
75+
76+
func setDefaultValueToInt(field *Field, defaultValue string) {
77+
value, _ := strconv.ParseInt(defaultValue, 10, 64)
78+
field.Value.SetInt(value)
79+
}
80+
81+
func setDefaultValueToFloat(field *Field, defaultValue string) {
82+
value, _ := strconv.ParseFloat(defaultValue, 64)
83+
field.Value.SetFloat(value)
84+
}
85+
86+
func setDefaultValueToUint(field *Field, defaultValue string) {
87+
value, _ := strconv.ParseUint(defaultValue, 10, 64)
88+
field.Value.SetUint(value)
89+
}
90+
91+
func setDefaultValueToSlice(field *Field, defaultValue string) {
92+
if field.Value.Type().Elem().Kind() == reflect.Uint8 {
93+
field.Value.SetBytes([]byte(defaultValue))
94+
}
95+
}
96+
97+
func setDefaultValueToString(field *Field, defaultValue string) {
98+
field.Value.SetString(defaultValue)
99+
}
100+
101+
func setDefaultValueToStruct(field *Field, defaultValue string) {
102+
fields := getFieldsFromValue(field.Value)
103+
setDefaultValues(fields)
104+
}

defaults_test.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package defaults
2+
3+
import (
4+
"testing"
5+
)
6+
import . "launchpad.net/gocheck"
7+
8+
// Hook up gocheck into the "go test" runner.
9+
func Test(t *testing.T) { TestingT(t) }
10+
11+
type DefaultsSuite struct{}
12+
13+
var _ = Suite(&DefaultsSuite{})
14+
15+
type ExampleBasic struct {
16+
Bool bool `default:"true"`
17+
Integer int `default:"33"`
18+
Integer8 int8 `default:"8"`
19+
Integer16 int16 `default:"16"`
20+
Integer32 int32 `default:"32"`
21+
Integer64 int64 `default:"64"`
22+
UInteger uint `default:"11"`
23+
UInteger8 uint8 `default:"18"`
24+
UInteger16 uint16 `default:"116"`
25+
UInteger32 uint32 `default:"132"`
26+
UInteger64 uint64 `default:"164"`
27+
String string `default:"foo"`
28+
Bytes []byte `default:"bar"`
29+
Float32 float32 `default:"3.2"`
30+
Float64 float64 `default:"6.4"`
31+
Struct struct {
32+
Bool bool `default:"true"`
33+
Integer int `default:"33"`
34+
}
35+
}
36+
37+
func (self *DefaultsSuite) TestSetDefaultsBasic(c *C) {
38+
foo := &ExampleBasic{}
39+
SetDefaults(foo)
40+
41+
self.assertTypes(c, foo)
42+
}
43+
44+
type ExampleNested struct {
45+
Struct ExampleBasic
46+
}
47+
48+
func (self *DefaultsSuite) TestSetDefaultsNested(c *C) {
49+
foo := &ExampleNested{}
50+
SetDefaults(foo)
51+
52+
self.assertTypes(c, &foo.Struct)
53+
}
54+
55+
func (self *DefaultsSuite) assertTypes(c *C, foo *ExampleBasic) {
56+
c.Assert(foo.Bool, Equals, true)
57+
c.Assert(foo.Integer, Equals, 33)
58+
c.Assert(foo.Integer8, Equals, int8(8))
59+
c.Assert(foo.Integer16, Equals, int16(16))
60+
c.Assert(foo.Integer32, Equals, int32(32))
61+
c.Assert(foo.Integer64, Equals, int64(64))
62+
c.Assert(foo.UInteger, Equals, uint(11))
63+
c.Assert(foo.UInteger8, Equals, uint8(18))
64+
c.Assert(foo.UInteger16, Equals, uint16(116))
65+
c.Assert(foo.UInteger32, Equals, uint32(132))
66+
c.Assert(foo.UInteger64, Equals, uint64(164))
67+
c.Assert(foo.String, Equals, "foo")
68+
c.Assert(string(foo.Bytes), Equals, "bar")
69+
c.Assert(foo.Float32, Equals, float32(3.2))
70+
c.Assert(foo.Float64, Equals, 6.4)
71+
c.Assert(foo.Struct.Bool, Equals, true)
72+
}

0 commit comments

Comments
 (0)