Skip to content

Commit cb5df5f

Browse files
Merge pull request #273 from spf13/fix-indiretion
fix: indirection of typed nils
2 parents a79ffed + 1b425f3 commit cb5df5f

5 files changed

Lines changed: 71 additions & 4 deletions

File tree

basic_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import (
1515
)
1616

1717
func TestBool(t *testing.T) {
18+
var ptr *bool
19+
1820
testCases := []testCase{
1921
{0, false, false},
2022
{int(0), false, false},
@@ -36,6 +38,7 @@ func TestBool(t *testing.T) {
3638
{json.Number("0"), false, false},
3739

3840
{nil, false, false},
41+
{ptr, false, false},
3942
{"false", false, false},
4043
{"FALSE", false, false},
4144
{"False", false, false},
@@ -103,6 +106,8 @@ func TestString(t *testing.T) {
103106
}
104107
key := &Key{"foo"}
105108

109+
var ptr *string
110+
106111
testCases := []testCase{
107112
{int(8), "8", false},
108113
{int8(8), "8", false},
@@ -120,6 +125,7 @@ func TestString(t *testing.T) {
120125
{true, "true", false},
121126
{false, "false", false},
122127
{nil, "", false},
128+
{ptr, "", false},
123129
{[]byte("one time"), "one time", false},
124130
{"one more time", "one more time", false},
125131
{template.HTML("one time"), "one time", false},

indirect.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@ func indirect(i any) (any, bool) {
2424
}
2525

2626
v := reflect.ValueOf(i)
27-
for v.Kind() == reflect.Ptr && !v.IsNil() {
27+
28+
for v.Kind() == reflect.Ptr || (v.Kind() == reflect.Interface && v.Elem().Kind() == reflect.Ptr) {
29+
if v.IsNil() {
30+
return nil, true
31+
}
32+
2833
v = v.Elem()
2934
}
3035

indirect_test.go

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,56 @@ import (
1111
qt "github.com/frankban/quicktest"
1212
)
1313

14-
func TestIndirectPointers(t *testing.T) {
14+
func TestIndirect(t *testing.T) {
1515
c := qt.New(t)
1616

1717
x := 13
1818
y := &x
1919
z := &y
2020

21-
c.Assert(ToInt(y), qt.Equals, 13)
22-
c.Assert(ToInt(z), qt.Equals, 13)
21+
var ptr *string
22+
var ptrptr **string
23+
24+
var i any
25+
26+
var n = int(13)
27+
var i2 any = n
28+
29+
var i3 any = &n
30+
31+
var b *bool
32+
var i4 any = b
33+
34+
testCases := []struct {
35+
input any
36+
expected any
37+
expectedOk bool
38+
}{
39+
{x, 13, false},
40+
{y, 13, true},
41+
{z, 13, true},
42+
{ptr, nil, true},
43+
{ptrptr, nil, true},
44+
{i, nil, false},
45+
{&i, nil, true},
46+
{i2, 13, false},
47+
{&i2, 13, true},
48+
{i3, 13, true},
49+
{&i3, 13, true},
50+
{i4, nil, true},
51+
{&i4, nil, true},
52+
{nil, nil, false},
53+
}
54+
55+
for _, testCase := range testCases {
56+
// TODO: remove after minimum Go version is >=1.22
57+
testCase := testCase
58+
59+
t.Run("", func(t *testing.T) {
60+
v, ok := indirect(testCase.input)
61+
62+
c.Assert(v, qt.Equals, testCase.expected)
63+
c.Assert(ok, qt.Equals, testCase.expectedOk)
64+
})
65+
}
2366
}

time.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ func ToTimeInDefaultLocationE(i any, location *time.Location) (tim time.Time, er
5353
return time.Unix(int64(v), 0), nil
5454
case uint64:
5555
return time.Unix(int64(v), 0), nil
56+
case nil:
57+
return time.Time{}, nil
5658
default:
5759
return time.Time{}, fmt.Errorf(errorMsg, i, i, time.Time{})
5860
}
@@ -87,6 +89,8 @@ func ToDurationE(i any) (time.Duration, error) {
8789
}
8890

8991
return time.ParseDuration(s)
92+
case nil:
93+
return time.Duration(0), nil
9094
default:
9195
if i, ok := resolveAlias(i); ok {
9296
return ToDurationE(i)

time_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import (
1919
)
2020

2121
func TestTime(t *testing.T) {
22+
var ptr *time.Time
23+
2224
testCases := []testCase{
2325
{"2009-11-10 23:00:00 +0000 UTC", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // Time.String()
2426
{"Tue Nov 10 23:00:00 2009", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false}, // ANSIC
@@ -56,6 +58,8 @@ func TestTime(t *testing.T) {
5658
{json.Number("1234567890"), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
5759
{time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
5860

61+
{ptr, time.Time{}, false},
62+
5963
// Failure cases
6064
{"2006", time.Time{}, true},
6165
{json.Number("123.4567890"), time.Time{}, true},
@@ -68,6 +72,8 @@ func TestTime(t *testing.T) {
6872
func TestDuration(t *testing.T) {
6973
type MyDuration time.Duration
7074

75+
var ptr *time.Duration
76+
7177
var expected time.Duration = 5
7278

7379
testCases := []testCase{
@@ -94,6 +100,9 @@ func TestDuration(t *testing.T) {
94100
{string("5m"), time.Minute * expected, false},
95101
{string("5h"), time.Hour * expected, false},
96102

103+
{0, time.Duration(0), false},
104+
{ptr, time.Duration(0), false},
105+
97106
// Aliases
98107
{MyInt(5), expected, false},
99108
{MyString("5"), expected, false},

0 commit comments

Comments
 (0)