]> Sergey Matveev's repositories - btrtrc.git/commitdiff
bencode: Improve support for embedded structs
authorMatt Joiner <anacrolix@gmail.com>
Mon, 24 May 2021 07:31:52 +0000 (17:31 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Mon, 7 Jun 2021 03:01:40 +0000 (13:01 +1000)
bencode/decode.go
bencode/encode.go

index e891f5be0dc8b868d136d3003721a45729e365e8..43bb9ce69493cae2a90ee6eadcb944ca2b4f8328 100644 (file)
@@ -253,14 +253,19 @@ func parseStructFields(struct_ reflect.Type, each func(key string, df dictField)
                i := _i
                f := struct_.Field(i)
                if f.Anonymous {
-                       parseStructFields(f.Type.Elem(), func(key string, df dictField) {
+                       t := f.Type
+                       if t.Kind() == reflect.Ptr {
+                               t = t.Elem()
+                       }
+                       parseStructFields(t, func(key string, df dictField) {
                                innerGet := df.Get
                                df.Get = func(value reflect.Value) func(reflect.Value) {
                                        anonPtr := value.Field(i)
-                                       if anonPtr.IsNil() {
+                                       if anonPtr.Kind() == reflect.Ptr && anonPtr.IsNil() {
                                                anonPtr.Set(reflect.New(f.Type.Elem()))
+                                               anonPtr = anonPtr.Elem()
                                        }
-                                       return innerGet(anonPtr.Elem())
+                                       return innerGet(anonPtr)
                                }
                                each(key, df)
                        })
index f25cfef82bdf4ed70df4728f5f3bf119a9a1c462..05153a8c273beb5d62a5bc035b31b02fc71a11f3 100644 (file)
@@ -231,16 +231,24 @@ func makeEncodeFields(t reflect.Type) (fs []encodeField) {
                        continue
                }
                if f.Anonymous {
-                       anonEFs := makeEncodeFields(f.Type.Elem())
+                       t := f.Type
+                       if t.Kind() == reflect.Ptr {
+                               t = t.Elem()
+                       }
+                       anonEFs := makeEncodeFields(t)
                        for aefi := range anonEFs {
                                anonEF := anonEFs[aefi]
                                bottomField := anonEF
                                bottomField.i = func(v reflect.Value) reflect.Value {
                                        v = v.Field(i)
-                                       if v.IsNil() {
-                                               return reflect.Value{}
+                                       if v.Kind() == reflect.Ptr {
+                                               if v.IsNil() {
+                                                       // This will skip serializing this value.
+                                                       return reflect.Value{}
+                                               }
+                                               v = v.Elem()
                                        }
-                                       return anonEF.i(v.Elem())
+                                       return anonEF.i(v)
                                }
                                fs = append(fs, bottomField)
                        }