Skip to content

Commit

Permalink
Merge pull request #6 from soranoba/fix/text-unmarshaler
Browse files Browse the repository at this point in the history
Fixed a bug that TextUnmarshaler does not work.
  • Loading branch information
soranoba authored Sep 19, 2020
2 parents 95815ad + edbf7d3 commit c63d507
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 24 deletions.
16 changes: 11 additions & 5 deletions accessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,22 @@ type field struct {
}

func newAccessor(tag *tag, v reflect.Value) accessor {
switch reflect.Indirect(v).Kind() {
iv := reflect.Indirect(v)
switch iv.Kind() {
case reflect.Array, reflect.Slice:
return &arrayAccessor{tag: tag, value: reflect.Indirect(v)}
return &arrayAccessor{tag: tag, value: iv}
case reflect.Struct:
sv := reflect.Indirect(v)
t := sv.Type()
if iv.CanAddr() {
if iv.Addr().Type().Implements(reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()) {
return newValueAccessor(v)
}
}

t := iv.Type()
fields := make(map[string]*field)
for i := 0; i < t.NumField(); i++ {
structField := t.Field(i)
fieldValue := sv.Field(i)
fieldValue := iv.Field(i)
if !fieldValue.CanSet() {
continue
}
Expand Down
16 changes: 8 additions & 8 deletions accessor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ import (

func Test_ValueAccessor(t *testing.T) {
var s string
ac := newValueAccessor(reflect.ValueOf(s)) // string
ac := newAccessor(nil, reflect.ValueOf(s)) // string
assertError(t, ac.Set("og:title", "title"))

ac = newValueAccessor(reflect.ValueOf(&s)) // *string
ac = newAccessor(nil, reflect.ValueOf(&s)) // *string
assertNoError(t, ac.Set("og:title", "title"))
assertEqual(t, s, "title")
assertNoError(t, ac.Set("og:title", "title2"))
assertEqual(t, s, "title") // cannot overwrite

var time time.Time
ac = newValueAccessor(reflect.ValueOf(time)) // URL
ac = newAccessor(nil, reflect.ValueOf(time)) // Time
assertError(t, ac.Set("video:release_date", "2020-05-20T01:01:25Z"))

ac = newValueAccessor(reflect.ValueOf(&time)) // *URL
ac = newAccessor(nil, reflect.ValueOf(&time)) // *Time
assertNoError(t, ac.Set("video:release_date", "2020-05-20T01:01:25Z"))
assertEqual(t, time.String(), "2020-05-20 01:01:25 +0000 UTC")

Expand All @@ -42,10 +42,10 @@ func Test_ValueAccessor(t *testing.T) {
assertEqual(t, u, uint(123))

var f float64
ac = newValueAccessor(reflect.ValueOf(f)) // float64
ac = newAccessor(nil, reflect.ValueOf(f)) // float64
assertError(t, ac.Set("og:number", "23.5"))

ac = newValueAccessor(reflect.ValueOf(&f)) // *float64
ac = newAccessor(nil, reflect.ValueOf(&f)) // *float64
assertNoError(t, ac.Set("og:number", "23.5"))
assertEqual(t, f, float64(23.5))
}
Expand Down Expand Up @@ -109,7 +109,7 @@ func Test_StructAccessor(t *testing.T) {
var v struct {
Title string `googp:"og:title"`
Description *string `googp:"og:description"`
Url *string `googp:"og:url"`
URL *string `googp:"og:url"`
}

ac := newAccessor(nil, reflect.ValueOf(v))
Expand All @@ -121,7 +121,7 @@ func Test_StructAccessor(t *testing.T) {
assertNoError(t, ac.Set("og:description", "description"))
assertEqual(t, v.Title, "title")
assertEqual(t, *v.Description, "description")
assertEqual(t, v.Url, (*string)(nil))
assertEqual(t, v.URL, (*string)(nil))
}

func Test_StructAccessor_ConflictTag(t *testing.T) {
Expand Down
38 changes: 27 additions & 11 deletions googp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,35 +52,51 @@ func ExampleFetch() {
return
}

fmt.Printf("og:title = \"%s\"", ogp.Title)
fmt.Printf("og:type = \"%s\"", ogp.Type)
fmt.Printf("og:url = \"%s\"", ogp.URL)
fmt.Printf("og:title = \"%s\"\n", ogp.Title)
fmt.Printf("og:type = \"%s\"\n", ogp.Type)
fmt.Printf("og:url = \"%s\"\n", ogp.URL)

// Outputs:
// Output:
// og:title = "Open Graph protocol"
// og:type = "website"
// og:url = "https://ogp.me/"
}

type URL struct {
url.URL
}

func (url *URL) UnmarshalText(text []byte) error {
u, err := url.Parse(string(text))
if err != nil {
return err
}
url.URL = *u
return nil
}

func ExampleFetch_customizeModel() {
type MyOGP struct {
Title string `googp:"og:title"`
URL url.URL `googp:"og:url"`
AppID int `googp:"fb:app_id"`
Title string `googp:"og:title"`
URL URL `googp:"og:url"`
ImageURL *URL `googp:"og:image"`
AppID int `googp:"fb:app_id"`
}

var ogp MyOGP
if err := Fetch("https://ogp.me", &ogp); err != nil {
return
}

fmt.Printf("og:title = \"%s\"", ogp.Title)
fmt.Printf("og:url = \"%s\"", ogp.URL.String())
fmt.Printf("fb:app_id = \"%d\"", ogp.AppID)
fmt.Printf("og:title = \"%s\"\n", ogp.Title)
fmt.Printf("og:url = \"%s\"\n", ogp.URL.String())
fmt.Printf("og:image = \"%s\"\n", ogp.ImageURL.String())
fmt.Printf("fb:app_id = %d\n", ogp.AppID)

// Outputs:
// Output:
// og:title = "Open Graph protocol"
// og:url = "https://ogp.me/"
// og:image = "https://ogp.me/logo.png"
// fb:app_id = 115190258555800
}

Expand Down

0 comments on commit c63d507

Please sign in to comment.