From f7ef98fea662d1d43d9a79c8277762649e953dd1 Mon Sep 17 00:00:00 2001 From: will butler Date: Mon, 1 May 2023 14:10:33 -0400 Subject: [PATCH] tagged defaults --- .gitignore | 1 + defaults.go | 10 ++++++++++ defaults_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ setter.go | 11 +++++++++++ 4 files changed, 64 insertions(+) diff --git a/.gitignore b/.gitignore index e43b0f9..8d979a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .DS_Store +.idea/* diff --git a/defaults.go b/defaults.go index b5e7eb9..cf404a2 100644 --- a/defaults.go +++ b/defaults.go @@ -34,6 +34,16 @@ func Set(ptr interface{}) error { for i := 0; i < t.NumField(); i++ { if defaultVal := t.Field(i).Tag.Get(fieldName); defaultVal != "-" { + if t.Field(i).IsExported() { + iface := v.Field(i).Addr().Interface() + if taggedSetter, ok := iface.(TaggedSetter); ok { + if err := taggedSetter.SetTaggedDefaults(defaultVal); err != nil { + return err + } + continue + } + } + if err := setField(v.Field(i), defaultVal); err != nil { return err } diff --git a/defaults_test.go b/defaults_test.go index 350ad62..de9f18c 100644 --- a/defaults_test.go +++ b/defaults_test.go @@ -6,6 +6,7 @@ import ( "net" "reflect" "strconv" + "strings" "testing" "time" @@ -757,3 +758,44 @@ func TestDefaultsSetter(t *testing.T) { t.Errorf("expected 1 for MainInt, got %d", main.MainInt) } } + +type Duration struct { + time.Duration +} + +func (d *Duration) SetTaggedDefaults(tag string) (err error) { + d.Duration, err = time.ParseDuration(tag) + return +} + +type TaggedDefaults struct { + Duration Duration `default:"1s"` +} + +func TestTaggedDefaultsSetterHappy(t *testing.T) { + sample := &TaggedDefaults{} + err := Set(sample) + if err != nil { + t.Errorf("unexpected error: %s", err) + } + + if sample.Duration.Duration != time.Second { + t.Errorf("expected 1s for Duration, got %s", sample.Duration.Duration) + } +} + +type TaggedDefaultsSad struct { + Duration Duration `default:"invalid"` +} + +func TestTaggedDefaultsSetterSad(t *testing.T) { + sample := &TaggedDefaultsSad{} + err := Set(sample) + if err == nil { + t.Error("unexpected success?!") + } + + if !strings.HasPrefix(err.Error(), "time: invalid duration") { + t.Errorf("unexpected error: %s", err) + } +} diff --git a/setter.go b/setter.go index 1f64aa6..05a27e4 100644 --- a/setter.go +++ b/setter.go @@ -10,3 +10,14 @@ func callSetter(v interface{}) { ds.SetDefaults() } } + +type TaggedSetter interface { + SetTaggedDefaults(tag string) error +} + +func callTaggedSetter(v interface{}, tag string) error { + if ds, ok := v.(TaggedSetter); ok { + return ds.SetTaggedDefaults(tag) + } + return nil +}