(bz []byte, rv reflect.Value)
| 202 | } |
| 203 | |
| 204 | func decodeReflectInterface(bz []byte, rv reflect.Value) error { |
| 205 | if !rv.CanAddr() { |
| 206 | return errors.New("interface value not addressable") |
| 207 | } |
| 208 | |
| 209 | // Decode the interface wrapper. |
| 210 | wrapper := interfaceWrapper{} |
| 211 | if err := json.Unmarshal(bz, &wrapper); err != nil { |
| 212 | return err |
| 213 | } |
| 214 | if wrapper.Type == "" { |
| 215 | return errors.New("interface type cannot be empty") |
| 216 | } |
| 217 | if len(wrapper.Value) == 0 { |
| 218 | return errors.New("interface value cannot be empty") |
| 219 | } |
| 220 | |
| 221 | // Dereference-and-construct pointers, to handle nested pointers. |
| 222 | for rv.Kind() == reflect.Ptr { |
| 223 | if rv.IsNil() { |
| 224 | rv.Set(reflect.New(rv.Type().Elem())) |
| 225 | } |
| 226 | rv = rv.Elem() |
| 227 | } |
| 228 | |
| 229 | // Look up the interface type, and construct a concrete value. |
| 230 | rt, returnPtr := typeRegistry.lookup(wrapper.Type) |
| 231 | if rt == nil { |
| 232 | return fmt.Errorf("unknown type %q", wrapper.Type) |
| 233 | } |
| 234 | |
| 235 | cptr := reflect.New(rt) |
| 236 | crv := cptr.Elem() |
| 237 | if err := decodeReflect(wrapper.Value, crv); err != nil { |
| 238 | return err |
| 239 | } |
| 240 | |
| 241 | // This makes sure interface implementations with pointer receivers (e.g. func (c *Car)) are |
| 242 | // constructed as pointers behind the interface. The types must be registered as pointers with |
| 243 | // RegisterType(). |
| 244 | if rv.Type().Kind() == reflect.Interface && returnPtr { |
| 245 | if !cptr.Type().AssignableTo(rv.Type()) { |
| 246 | return fmt.Errorf("invalid type %q for this value", wrapper.Type) |
| 247 | } |
| 248 | rv.Set(cptr) |
| 249 | } else { |
| 250 | if !crv.Type().AssignableTo(rv.Type()) { |
| 251 | return fmt.Errorf("invalid type %q for this value", wrapper.Type) |
| 252 | } |
| 253 | rv.Set(crv) |
| 254 | } |
| 255 | return nil |
| 256 | } |
| 257 | |
| 258 | func decodeStdlib(bz []byte, rv reflect.Value) error { |
| 259 | if !rv.CanAddr() && rv.Kind() != reflect.Ptr { |
no test coverage detected
searching dependent graphs…