Skip to content

Commit 0d14bac

Browse files
committed
fix(fill_struct): Work with non-pointer structs and pointers to non-structs
1 parent a9aec5a commit 0d14bac

File tree

3 files changed

+72
-13
lines changed

3 files changed

+72
-13
lines changed

api/remote.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func NewRemoteHandlers(node *p2p.QriNode) *RemoteHandlers {
2323
// ReceiveHandler is the endpoint for remotes to receive daginfo
2424
func (h *RemoteHandlers) ReceiveHandler(w http.ResponseWriter, r *http.Request) {
2525
switch r.Method {
26-
// no "OPTIONS" method here, because browsers should never hit this endpoint
26+
// no "OPTIONS" method here, because browsers should never hit this endpoint
2727
case "POST":
2828
h.receiveDataset(w, r)
2929
default:

base/fill_struct.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ type ArbitrarySetter interface {
2626
var (
2727
// timeObj and strObj are used for reflect.TypeOf
2828
timeObj time.Time
29-
strObj string
29+
strObj string
3030
)
3131

3232
// putFieldsToTargetStruct iterates over the fields in the target struct, and assigns each
@@ -154,9 +154,13 @@ func putValueToPlace(val interface{}, place reflect.Value) error {
154154
}
155155
return fmt.Errorf("need type time, value %s", val)
156156
}
157-
// Other struct types are not handled currently. Should probably do the same thing
158-
// as what's done for `pointer` below.
159-
return fmt.Errorf("unknown struct %s", place.Type())
157+
// Struct must be assigned from a map.
158+
component, err := toStringMap(val)
159+
if err != nil {
160+
return err
161+
}
162+
// Recursion to handle sub-component.
163+
return putFieldsToTargetStruct(component, place)
160164
case reflect.Map:
161165
if val == nil {
162166
// If map is nil, nothing more to do.
@@ -211,17 +215,11 @@ func putValueToPlace(val interface{}, place reflect.Value) error {
211215
alloc := reflect.New(place.Type().Elem())
212216
place.Set(alloc)
213217
inner := alloc.Elem()
214-
// For now, can only point to a struct.
215-
if inner.Kind() != reflect.Struct {
216-
return fmt.Errorf("can only assign to *struct")
217-
}
218-
// Struct must be assigned from a map.
219-
component, err := toStringMap(val)
218+
err := putValueToPlace(val, inner)
220219
if err != nil {
221220
return err
222221
}
223-
// Recursion to handle sub-component.
224-
return putFieldsToTargetStruct(component, inner)
222+
return nil
225223
default:
226224
return fmt.Errorf("unknown kind %s", place.Kind())
227225
}

base/fill_struct_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,12 @@ type Collection struct {
165165
Ptr *int
166166
Dict map[string]string
167167
List []string
168+
Sub SubElement
169+
}
170+
171+
type SubElement struct {
172+
Num int
173+
Things *map[string]string
168174
}
169175

170176
func (c *Collection) SetArbitrary(key string, val interface{}) error {
@@ -435,3 +441,58 @@ func TestNilPointer(t *testing.T) {
435441
t.Error("expected null Ptr")
436442
}
437443
}
444+
445+
func TestFillSubSection(t *testing.T) {
446+
jsonData := `{
447+
"Sub": {
448+
"Num": 7
449+
}
450+
}`
451+
452+
data := make(map[string]interface{})
453+
err := json.Unmarshal([]byte(jsonData), &data)
454+
if err != nil {
455+
panic(err)
456+
}
457+
458+
var c Collection
459+
err = FillStruct(data, &c)
460+
if err != nil {
461+
panic(err)
462+
}
463+
464+
if c.Sub.Num != 7 {
465+
t.Errorf("expected: c.Sub.Num should be 7, got: %d", c.Sub.Num)
466+
}
467+
}
468+
469+
func TestFillPointerToMap(t *testing.T) {
470+
jsonData := `{
471+
"Things": {
472+
"a": "apple",
473+
"b": "banana"
474+
}
475+
}`
476+
477+
data := make(map[string]interface{})
478+
err := json.Unmarshal([]byte(jsonData), &data)
479+
if err != nil {
480+
panic(err)
481+
}
482+
483+
var s SubElement
484+
err = FillStruct(data, &s)
485+
if err != nil {
486+
panic(err)
487+
}
488+
489+
if s.Things == nil {
490+
t.Errorf("expected: s.Things should be non-nil")
491+
}
492+
if (*s.Things)["a"] != "apple" {
493+
t.Errorf("expected: s.Things[\"a\"] should be \"apple\"")
494+
}
495+
if (*s.Things)["b"] != "banana" {
496+
t.Errorf("expected: s.Things[\"b\"] should be \"banana\"")
497+
}
498+
}

0 commit comments

Comments
 (0)