Skip to content

Commit 2c8bb9a

Browse files
committed
feat: 在结构体转换中添加字符串到时间Duration的钩子函数
1 parent ce5c711 commit 2c8bb9a

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

complex/hooks.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,22 @@ func stringToTimeHookFunc() HookFunc {
2525
}
2626
}
2727

28+
// stringToDurationHookFunc returns a HookFunc that converts string to time.Duration.
29+
func stringToDurationHookFunc() HookFunc {
30+
return func(from reflect.Type, to reflect.Type, data interface{}) (interface{}, error) {
31+
if from.Kind() != reflect.String || to != reflect.TypeOf(time.Duration(0)) {
32+
return data, nil
33+
}
34+
35+
s, ok := data.(string)
36+
if !ok {
37+
return data, nil
38+
}
39+
40+
return basic.ToDurationE(s)
41+
}
42+
}
43+
2844
// intToBoolHookFunc returns a HookFunc that converts integer to bool.
2945
func intToBoolHookFunc() HookFunc {
3046
return func(from reflect.Type, to reflect.Type, data interface{}) (interface{}, error) {

complex/struct.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func StructE(source, pointer interface{}, hooks ...HookFunc) error {
3333
}
3434

3535
// Prepend default hooks
36-
allHooks := []HookFunc{stringToTimeHookFunc(), intToBoolHookFunc()}
36+
allHooks := []HookFunc{stringToTimeHookFunc(), stringToDurationHookFunc(), intToBoolHookFunc()}
3737
allHooks = append(allHooks, hooks...)
3838

3939
// Get the reflect.Value of the pointer and the struct

test/struct_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ type UserWithBoolFloat struct {
4848
Balance float32
4949
}
5050

51+
type TestDuration struct {
52+
ID int
53+
Duration time.Duration `mconv:"duration"`
54+
}
55+
5156
func TestStruct(t *testing.T) {
5257
t.Run("SimpleConversion", func(t *testing.T) {
5358
source := map[string]interface{}{"ID": 1, "Name": "Alice"}
@@ -172,6 +177,24 @@ func TestStruct(t *testing.T) {
172177
}
173178
})
174179

180+
t.Run("BuiltInStringToDurationHook", func(t *testing.T) {
181+
source := map[string]interface{}{
182+
"duration": "30s",
183+
}
184+
var target TestDuration
185+
err := complex.StructE(source, &target)
186+
if err != nil {
187+
t.Fatalf("unexpected error: %v", err)
188+
}
189+
190+
expected := TestDuration{
191+
Duration: 30 * time.Second,
192+
}
193+
if !reflect.DeepEqual(target, expected) {
194+
t.Errorf("expected %+v, got %+v", expected, target)
195+
}
196+
})
197+
175198
t.Run("CustomHook", func(t *testing.T) {
176199
type HookUser struct {
177200
ID int

0 commit comments

Comments
 (0)