decoder: handle casting local date into time.Time

Refs #494
This commit is contained in:
Thomas Pelletier
2021-04-08 08:00:31 -04:00
parent 18af62d3ea
commit 275e366c17
3 changed files with 33 additions and 0 deletions
+1
View File
@@ -23,6 +23,7 @@ Development branch. Use at your own risk.
- [x] Original go-toml testgen tests pass.
- [x] Track file position (line, column) for errors.
- [ ] Strict mode.
- [ ] Document Unmarshal / Decode
### Marshal
+17
View File
@@ -30,6 +30,9 @@ func NewDecoder(r io.Reader) *Decoder {
}
// Decode the whole content of r into v.
//
// When a TOML local date is decoded into a time.Time, its value is represented
// in time.Local timezone.
func (d *Decoder) Decode(v interface{}) error {
b, err := ioutil.ReadAll(d.r)
if err != nil {
@@ -224,6 +227,13 @@ func tryTextUnmarshaler(x target, node ast.Node) (bool, error) {
if v.Kind() != reflect.Struct {
return false, nil
}
// Special case for time, becase we allow to unmarshal to it from
// different kind of AST nodes.
if v.Type() == timeType {
return false, nil
}
if v.Type().Implements(textUnmarshalerType) {
return true, v.Interface().(encoding.TextUnmarshaler).UnmarshalText(node.Data)
}
@@ -313,7 +323,14 @@ func setDateTime(x target, v time.Time) error {
return x.set(reflect.ValueOf(v))
}
var timeType = reflect.TypeOf(time.Time{})
func setDate(x target, v LocalDate) error {
if x.get().Type() == timeType {
cast := v.In(time.Local)
return setDateTime(x, cast)
}
return x.set(reflect.ValueOf(v))
}
+15
View File
@@ -4,6 +4,7 @@ import (
"math"
"strconv"
"testing"
"time"
"github.com/pelletier/go-toml/v2"
"github.com/stretchr/testify/assert"
@@ -780,6 +781,20 @@ val1 = "test1"
require.Equal(t, "test2", cfg.Val2)
}
func TestIssue494(t *testing.T) {
data := `
foo = 2021-04-08
bar = 2021-04-08
`
type s struct {
Foo time.Time `toml:"foo"`
Bar time.Time `toml:"bar"`
}
ss := new(s)
err := toml.Unmarshal([]byte(data), ss)
require.NoError(t, err)
}
func TestUnmarshalDecodeErrors(t *testing.T) {
examples := []struct {
desc string