Skip to content

Commit 125f779

Browse files
authored
Merge pull request #53 from cpuguy83/main_fix_json
Fix unmarshalling of registered types
2 parents a1e63f0 + 75963df commit 125f779

File tree

2 files changed

+34
-11
lines changed

2 files changed

+34
-11
lines changed

types.go

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ func MarshalAnyToProto(from interface{}) (*anypb.Any, error) {
216216
}
217217

218218
func unmarshal(typeURL string, value []byte, v interface{}) (interface{}, error) {
219-
t, err := getTypeByUrl(typeURL)
219+
t, isProto, err := getTypeByUrl(typeURL)
220220
if err != nil {
221221
return nil, err
222222
}
@@ -234,31 +234,32 @@ func unmarshal(typeURL string, value []byte, v interface{}) (interface{}, error)
234234
}
235235
}
236236

237-
pm, ok := v.(proto.Message)
238-
if ok {
239-
err = proto.Unmarshal(value, pm)
240-
} else {
241-
err = json.Unmarshal(value, v)
237+
if isProto {
238+
pm, ok := v.(proto.Message)
239+
if ok {
240+
err = proto.Unmarshal(value, pm)
241+
return v, err
242+
}
242243
}
244+
return v, json.Unmarshal(value, v)
243245

244-
return v, err
245246
}
246247

247-
func getTypeByUrl(url string) (reflect.Type, error) {
248+
func getTypeByUrl(url string) (_ reflect.Type, isProto bool, _ error) {
248249
mu.RLock()
249250
for t, u := range registry {
250251
if u == url {
251252
mu.RUnlock()
252-
return t, nil
253+
return t, false, nil
253254
}
254255
}
255256
mu.RUnlock()
256257
mt, err := protoregistry.GlobalTypes.FindMessageByURL(url)
257258
if err != nil {
258-
return nil, fmt.Errorf("type with url %s: %w", url, ErrNotFound)
259+
return nil, false, fmt.Errorf("type with url %s: %w", url, ErrNotFound)
259260
}
260261
empty := mt.New().Interface()
261-
return reflect.TypeOf(empty).Elem(), nil
262+
return reflect.TypeOf(empty).Elem(), true, nil
262263
}
263264

264265
func tryDereference(v interface{}) reflect.Type {

types_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package typeurl
1818

1919
import (
2020
"bytes"
21+
"encoding/json"
2122
"errors"
2223
"reflect"
2324
"testing"
@@ -241,3 +242,24 @@ func TestUnmarshalNotFound(t *testing.T) {
241242
t.Fatalf("unexpected error unmarshalling type which does not exist: %v", err)
242243
}
243244
}
245+
246+
func TestUnmarshalJSON(t *testing.T) {
247+
url := t.Name()
248+
Register(&timestamppb.Timestamp{}, url)
249+
250+
expected := timestamppb.Now()
251+
252+
dt, err := json.Marshal(expected)
253+
if err != nil {
254+
t.Fatal(err)
255+
}
256+
257+
var actual timestamppb.Timestamp
258+
if err := UnmarshalToByTypeURL(url, dt, &actual); err != nil {
259+
t.Fatal(err)
260+
}
261+
262+
if !expected.AsTime().Equal(actual.AsTime()) {
263+
t.Fatalf("expected value to be %q, got: %q", expected.AsTime(), actual.AsTime())
264+
}
265+
}

0 commit comments

Comments
 (0)