Skip to content

Commit 43ce150

Browse files
Add DoublePointer helper function (#764)
1 parent ebf2210 commit 43ce150

File tree

3 files changed

+97
-6
lines changed

3 files changed

+97
-6
lines changed

pointer_helpers.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,29 @@ Example:
2323
func Pointer[T any](value T) *T {
2424
return &value
2525
}
26+
27+
// DoublePointer creates a double pointer to a value of type T.
28+
//
29+
// This is useful for APIs that distinguish between null and omitted fields.
30+
//
31+
// Example:
32+
//
33+
// // For a field that should be non-null value in the API payload:
34+
// value := linodego.DoublePointer(42) // Returns **int pointing a *int pointer pointing to 42
35+
//
36+
// // For a field that should be null in the API payload, use `DoublePointerNull` function instead:
37+
// nullValue := linodego.DoublePointerNull[int]() // Returns **int that is nil
38+
//
39+
// // For a field that should not be included in the API payload, simply not include it in the struct.
40+
func DoublePointer[T any](value T) **T {
41+
valuePtr := &value
42+
return &valuePtr
43+
}
44+
45+
// DoublePointerNull creates a double pointer pointing to a nil pointer of type T,
46+
// indicating that the field should be null in the API payload.
47+
//
48+
// This is useful for APIs that distinguish between null and omitted fields.
49+
func DoublePointerNull[T any]() **T {
50+
return Pointer[*T](nil)
51+
}

pointer_helpers_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ import (
66

77
// TestPointer tests the Pointer helper function with various types
88
func TestPointer(t *testing.T) {
9+
// Test nil pointer for int (should be nil if explicitly set)
10+
nilIntPtr := Pointer[*int](nil)
11+
if nilIntPtr == nil || *nilIntPtr != nil {
12+
t.Errorf("Expected nil pointer, got %v", nilIntPtr)
13+
}
14+
915
// Test with an integer
1016
intValue := 11
1117
intPtr := Pointer(intValue)
@@ -45,3 +51,66 @@ func TestPointer(t *testing.T) {
4551
t.Errorf("Expected %+v, got %+v", structValue, *structPtr)
4652
}
4753
}
54+
55+
// TestDoublePointer tests the DoublePointer helper function with various types
56+
func TestDoublePointer(t *testing.T) {
57+
// Test with an integer
58+
intValue := 42
59+
intDoublePtr := DoublePointer(intValue)
60+
if **intDoublePtr != intValue {
61+
t.Errorf("Expected %d, got %d", intValue, **intDoublePtr)
62+
}
63+
64+
// Test with a string
65+
strValue := "double"
66+
strDoublePtr := DoublePointer(strValue)
67+
if **strDoublePtr != strValue {
68+
t.Errorf("Expected %s, got %s", strValue, **strDoublePtr)
69+
}
70+
71+
// Test with a boolean
72+
boolValue := false
73+
boolDoublePtr := DoublePointer(boolValue)
74+
if **boolDoublePtr != boolValue {
75+
t.Errorf("Expected %t, got %t", boolValue, **boolDoublePtr)
76+
}
77+
78+
// Test with a struct
79+
type myStruct struct {
80+
Field int
81+
}
82+
structValue := myStruct{Field: 7}
83+
structDoublePtr := DoublePointer(structValue)
84+
if (**structDoublePtr).Field != structValue.Field {
85+
t.Errorf("Expected %+v, got %+v", structValue, **structDoublePtr)
86+
}
87+
}
88+
89+
func TestDoublePointerNull(t *testing.T) {
90+
// Test with an integer
91+
intDoublePtr := DoublePointerNull[int]()
92+
if intDoublePtr == nil || *intDoublePtr != nil {
93+
t.Errorf("Expected nil pointer, got %v", intDoublePtr)
94+
}
95+
96+
// Test with a string
97+
stringDoublePtr := DoublePointerNull[string]()
98+
if stringDoublePtr == nil || *stringDoublePtr != nil {
99+
t.Errorf("Expected nil pointer, got %v", stringDoublePtr)
100+
}
101+
102+
// Test with a boolean
103+
boolDoublePtr := DoublePointerNull[bool]()
104+
if boolDoublePtr == nil || *boolDoublePtr != nil {
105+
t.Errorf("Expected nil pointer, got %v", boolDoublePtr)
106+
}
107+
108+
// Test with a struct
109+
type myStruct struct {
110+
Field int
111+
}
112+
structDoublePtr := DoublePointerNull[myStruct]()
113+
if structDoublePtr == nil || *structDoublePtr != nil {
114+
t.Errorf("Expected nil pointer, got %v", structDoublePtr)
115+
}
116+
}

test/integration/mysql_db_config_test.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ func TestDatabaseMySQL_EngineConfig_Create_Fails_EmptyDoublePointerValue(t *test
219219
Engine: "mysql/8",
220220
EngineConfig: &linodego.MySQLDatabaseEngineConfig{
221221
MySQL: &linodego.MySQLDatabaseEngineConfigMySQL{
222-
InnoDBFTServerStopwordTable: DoublePointer(linodego.Pointer("")),
222+
InnoDBFTServerStopwordTable: linodego.DoublePointer(""),
223223
},
224224
},
225225
}
@@ -231,10 +231,6 @@ func TestDatabaseMySQL_EngineConfig_Create_Fails_EmptyDoublePointerValue(t *test
231231
assert.Contains(t, err.Error(), "Invalid format: must match pattern ^.+/.+$")
232232
}
233233

234-
func DoublePointer[T any](v *T) **T {
235-
return &v
236-
}
237-
238234
func createMySQLOptionsModifierNullableField() mysqlDatabaseModifier {
239235
return func(options *linodego.MySQLCreateOptions) {
240236
options.Label = "example-db-created-with-config"
@@ -264,7 +260,7 @@ func createMySQLOptionsModifier() mysqlDatabaseModifier {
264260
InnoDBChangeBufferMaxSize: linodego.Pointer(30),
265261
InnoDBFlushNeighbors: linodego.Pointer(1),
266262
InnoDBFTMinTokenSize: linodego.Pointer(3),
267-
InnoDBFTServerStopwordTable: DoublePointer(linodego.Pointer("mydb/stopwords")),
263+
InnoDBFTServerStopwordTable: linodego.DoublePointer("mydb/stopwords"),
268264
InnoDBLockWaitTimeout: linodego.Pointer(50),
269265
InnoDBLogBufferSize: linodego.Pointer(16777216),
270266
InnoDBOnlineAlterLogMaxSize: linodego.Pointer(134217728),

0 commit comments

Comments
 (0)