feat: add field comments, local time zone decoding and in-value cancellation
Test / test (push) Successful in 1m32s
Test / test (push) Successful in 1m32s
Assisted-by: GLM 5.3 Flash
This commit is contained in:
@@ -20,11 +20,13 @@ import (
|
||||
// UnmarshalerContext destination; entry points without one leave it nil.
|
||||
// nodes is the document's node index, present only when a destination can
|
||||
// reach an OrderedMap and the parse built the tree its key order is read
|
||||
// from.
|
||||
// from. loc is the zone a local date-time is carried in when it decodes into
|
||||
// a time.Time destination; nil keeps the wrapper-only default.
|
||||
type decoder struct {
|
||||
disallowUnknown bool
|
||||
ctx context.Context
|
||||
nodes nodeIndex
|
||||
loc *time.Location
|
||||
}
|
||||
|
||||
func newDecoder() *decoder { return &decoder{} }
|
||||
@@ -244,6 +246,24 @@ func (d *decoder) assign(data any, dst reflect.Value) error {
|
||||
return setOffsetDateTime(v, dst)
|
||||
case time.Time:
|
||||
return setDateTime(v, dst)
|
||||
case LocalDateTime:
|
||||
if dst.Type() == localDateTimeType {
|
||||
dst.Set(reflect.ValueOf(v))
|
||||
return nil
|
||||
}
|
||||
return d.setLocalTimeValue(v.Time, dst)
|
||||
case LocalDate:
|
||||
if dst.Type() == localDateType {
|
||||
dst.Set(reflect.ValueOf(v))
|
||||
return nil
|
||||
}
|
||||
return d.setLocalTimeValue(v.Time, dst)
|
||||
case LocalTime:
|
||||
if dst.Type() == localTimeType {
|
||||
dst.Set(reflect.ValueOf(v))
|
||||
return nil
|
||||
}
|
||||
return d.setLocalTimeValue(v.Time, dst)
|
||||
default:
|
||||
rv := reflect.ValueOf(data)
|
||||
if rv.IsValid() && dst.Type() == rv.Type() {
|
||||
@@ -464,6 +484,26 @@ func setDateTime(v time.Time, dst reflect.Value) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// setLocalTimeValue stores a local date-time value into a plain time.Time
|
||||
// destination, which the decoder permits only when LocalTimeLocation fixed
|
||||
// the zone the wall-clock value is carried in; without it the wrapper types
|
||||
// are the only destinations a local kind fills, as they always have been.
|
||||
func (d *decoder) setLocalTimeValue(t time.Time, dst reflect.Value) error {
|
||||
if dst.Type() == timeType {
|
||||
if d.loc != nil {
|
||||
// A local value is a wall clock, so the zone choice relabels it
|
||||
// rather than shifting the instant: 07:32 in the document is
|
||||
// 07:32 in the location, not an hour later.
|
||||
dst.Set(reflect.ValueOf(time.Date(
|
||||
t.Year(), t.Month(), t.Day(),
|
||||
t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), d.loc)))
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("interpres: cannot assign local date-time to time.Time; set Decoder.LocalTimeLocation to choose the zone")
|
||||
}
|
||||
return fmt.Errorf("interpres: cannot assign local date-time to %s", dst.Type())
|
||||
}
|
||||
|
||||
func setBasic(dst, val reflect.Value, kind string) error {
|
||||
if dst.Kind() != val.Kind() {
|
||||
return fmt.Errorf("interpres: cannot assign %s to %s", kind, dst.Type())
|
||||
|
||||
Reference in New Issue
Block a user