Skip to content

Commit dd27699

Browse files
mromaszewiczclaude
andcommitted
Strip nullable support, fix TextUnmarshaler placement
Remove nullable.Nullable deep object support (moved to separate repo). Move TextUnmarshaler check into case reflect.Struct after the legacy Date/time.Time handlers, so it catches types like uuid.UUID without intercepting time.Time date-only fallback parsing. Add early returns to the Date and time.Time blocks which previously fell through. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7eda76c commit dd27699

File tree

1 file changed

+8
-49
lines changed

1 file changed

+8
-49
lines changed

deepobject.go

Lines changed: 8 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@ import (
1616
"github.com/oapi-codegen/runtime/types"
1717
)
1818

19-
type nullableLike interface {
20-
SetNull()
21-
UnmarshalJSON(data []byte) error
22-
}
23-
2419
func marshalDeepObject(in interface{}, path []string) ([]string, error) {
2520
var result []string
2621

@@ -233,52 +228,8 @@ func assignPathValues(dst interface{}, pathValues fieldOrValue) error {
233228
iv := reflect.Indirect(v)
234229
it := iv.Type()
235230

236-
switch dst := v.Interface().(type) {
237-
case Binder:
238-
return dst.Bind(pathValues.value)
239-
case encoding.TextUnmarshaler:
240-
err := dst.UnmarshalText([]byte(pathValues.value))
241-
if err != nil {
242-
return fmt.Errorf("error unmarshalling text '%s': %w", pathValues.value, err)
243-
}
244-
245-
return nil
246-
}
247-
248231
switch it.Kind() {
249232
case reflect.Map:
250-
// If the value looks like nullable.Nullable[T], we need to handle it properly.
251-
if dst, ok := dst.(nullableLike); ok {
252-
if pathValues.value == "null" {
253-
dst.SetNull()
254-
255-
return nil
256-
}
257-
258-
// We create a new empty value, who's type is the same as the
259-
// 'T' in nullable.Nullable[T]. Because of how nullable.Nullable is
260-
// implemented, we can do that by getting the type's element type.
261-
data := reflect.New(it.Elem()).Interface()
262-
263-
// We now try to assign the path values to the new type.
264-
if err := assignPathValues(data, pathValues); err != nil {
265-
return err
266-
}
267-
268-
// We'll marshal the data so that we can unmarshal it into
269-
// the original nullable.Nullable value.
270-
dataBytes, err := json.Marshal(data)
271-
if err != nil {
272-
return err
273-
}
274-
275-
if err := dst.UnmarshalJSON(dataBytes); err != nil {
276-
return err
277-
}
278-
279-
return nil
280-
}
281-
282233
dstMap := reflect.MakeMap(iv.Type())
283234
for key, value := range pathValues.fields {
284235
dstKey := reflect.ValueOf(key)
@@ -326,6 +277,7 @@ func assignPathValues(dst interface{}, pathValues fieldOrValue) error {
326277
dst = reflect.Indirect(aPtr)
327278
}
328279
dst.Set(reflect.ValueOf(date))
280+
return nil
329281
}
330282
if it.ConvertibleTo(reflect.TypeOf(time.Time{})) {
331283
var tm time.Time
@@ -346,6 +298,13 @@ func assignPathValues(dst interface{}, pathValues fieldOrValue) error {
346298
dst = reflect.Indirect(aPtr)
347299
}
348300
dst.Set(reflect.ValueOf(tm))
301+
return nil
302+
}
303+
// For other struct types that implement TextUnmarshaler (e.g. uuid.UUID),
304+
// use that for binding. This comes after the legacy Date/time.Time checks
305+
// above which have special fallback format handling.
306+
if tu, ok := v.Interface().(encoding.TextUnmarshaler); ok {
307+
return tu.UnmarshalText([]byte(pathValues.value))
349308
}
350309
fieldMap, err := fieldIndicesByJSONTag(iv.Interface())
351310
if err != nil {

0 commit comments

Comments
 (0)