This repository has been archived by the owner on Dec 17, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add dereferencing with default value
This allows you to extract a value from a pointer by setting values for nil pointers instead of getting the default value.
- Loading branch information
Showing
3 changed files
with
357 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
// Copyright © 2019-2020 Vasiliy Vasilyuk. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// Package derefed contains helper routines for simplifying the getting of | ||
// optional fields of basic type. This allows you to get the value from the | ||
// pointer even if it is nil, and if the pointer is nil it returns a value of | ||
// second parameter. | ||
package derefed | ||
|
||
// Bool dereference a pointer bool from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Bool(v *bool, def bool) bool { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// Byte dereference a pointer byte from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Byte(v *byte, def byte) byte { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// Complex64 dereference a pointer complex64 from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Complex64(v *complex64, def complex64) complex64 { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// Complex128 dereference a pointer complex128 from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Complex128(v *complex128, def complex128) complex128 { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// Float32 dereference a pointer float32 from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Float32(v *float32, def float32) float32 { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// Float64 dereference a pointer float64 from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Float64(v *float64, def float64) float64 { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// Int dereference a pointer int from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Int(v *int, def int) int { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// Int8 dereference a pointer int8 from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Int8(v *int8, def int8) int8 { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// Int16 dereference a pointer int16 from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Int16(v *int16, def int16) int16 { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// Int32 dereference a pointer int32 from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Int32(v *int32, def int32) int32 { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// Int64 dereference a pointer int64 from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Int64(v *int64, def int64) int64 { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// Rune dereference a pointer rune from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Rune(v *rune, def rune) rune { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// String dereference a pointer string from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func String(v *string, def string) string { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// Uint dereference a pointer uint from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Uint(v *uint, def uint) uint { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// Uint8 dereference a pointer uint8 from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Uint8(v *uint8, def uint8) uint8 { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// Uint16 dereference a pointer uint16 from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Uint16(v *uint16, def uint16) uint16 { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// Uint32 dereference a pointer uint32 from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Uint32(v *uint32, def uint32) uint32 { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// Uint64 dereference a pointer uint64 from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Uint64(v *uint64, def uint64) uint64 { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} | ||
|
||
// Uintptr dereference a pointer uintptr from the structure of a literal or | ||
// variable, and if the pointer is nil it returns a value of second parameter. | ||
func Uintptr(v *uintptr, def uintptr) uintptr { | ||
if v == nil { | ||
return def | ||
} | ||
return *v | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
// Copyright © 2019-2020 Vasiliy Vasilyuk. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package derefed | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
"testing" | ||
) | ||
|
||
func equal(t testing.TB, expected, actual interface{}) { | ||
if h, ok := t.(interface{ Helper() }); ok { | ||
h.Helper() | ||
} | ||
|
||
t.Logf("expected: %q (%T), actual: %q (%T)", fmt.Sprint(expected), expected, fmt.Sprint(actual), actual) | ||
|
||
if !reflect.DeepEqual(expected, actual) { | ||
t.Fatalf("values obtained are not equal, expected: %v, actual: %v", expected, actual) | ||
} | ||
} | ||
|
||
var _bool = true | ||
var _byte = byte(1) | ||
var _complex64 = complex64(1.1) | ||
var _complex128 = complex128(1.1) | ||
var _float32 = float32(1.1) | ||
var _float64 = float64(1.1) | ||
var _int = int(1) | ||
var _int8 = int8(8) | ||
var _int16 = int16(16) | ||
var _int32 = int32(32) | ||
var _int64 = int64(64) | ||
var _rune = rune(1) | ||
var _string = "derefed" | ||
var _uint = uint(1) | ||
var _uint8 = uint8(8) | ||
var _uint16 = uint16(16) | ||
var _uint32 = uint32(32) | ||
var _uint64 = uint64(64) | ||
var _uintptr = uintptr(64) | ||
|
||
func TestBool(t *testing.T) { | ||
equal(t, false, Bool(nil, false)) | ||
equal(t, true, Bool(nil, true)) | ||
equal(t, false, Bool(new(bool), true)) | ||
equal(t, true, Bool(&_bool, false)) | ||
} | ||
|
||
func TestByte(t *testing.T) { | ||
equal(t, byte(0), Byte(nil, 0)) | ||
equal(t, byte(1), Byte(nil, 1)) | ||
equal(t, byte(0), Byte(new(byte), 1)) | ||
equal(t, byte(1), Byte(&_byte, 2)) | ||
} | ||
|
||
func TestComplex64(t *testing.T) { | ||
equal(t, complex64(0), Complex64(nil, 0)) | ||
equal(t, complex64(1.1), Complex64(nil, 1.1)) | ||
equal(t, complex64(0), Complex64(new(complex64), 2.2)) | ||
equal(t, complex64(1.1), Complex64(&_complex64, 2.2)) | ||
} | ||
|
||
func TestComplex128(t *testing.T) { | ||
equal(t, complex128(0), Complex128(nil, 0)) | ||
equal(t, complex128(1.1), Complex128(nil, 1.1)) | ||
equal(t, complex128(0), Complex128(new(complex128), 1.1)) | ||
equal(t, complex128(1.1), Complex128(&_complex128, 2.2)) | ||
} | ||
|
||
func TestFloat32(t *testing.T) { | ||
equal(t, float32(0), Float32(nil, 0)) | ||
equal(t, float32(1.1), Float32(nil, 1.1)) | ||
equal(t, float32(0), Float32(new(float32), 1.1)) | ||
equal(t, float32(1.1), Float32(&_float32, 2.2)) | ||
} | ||
|
||
func TestFloat64(t *testing.T) { | ||
equal(t, float64(0), Float64(nil, 0)) | ||
equal(t, float64(1.1), Float64(nil, 1.1)) | ||
equal(t, float64(0), Float64(new(float64), 1.1)) | ||
equal(t, float64(1.1), Float64(&_float64, 2.2)) | ||
} | ||
|
||
func TestInt(t *testing.T) { | ||
equal(t, 0, Int(nil, 0)) | ||
equal(t, 1, Int(nil, 1)) | ||
equal(t, 0, Int(new(int), 1)) | ||
equal(t, 1, Int(&_int, 2)) | ||
} | ||
|
||
func TestInt8(t *testing.T) { | ||
equal(t, int8(0), Int8(nil, 0)) | ||
equal(t, int8(1), Int8(nil, 1)) | ||
equal(t, int8(0), Int8(new(int8), 1)) | ||
equal(t, int8(8), Int8(&_int8, 2)) | ||
} | ||
|
||
func TestInt16(t *testing.T) { | ||
equal(t, int16(0), Int16(nil, 0)) | ||
equal(t, int16(1), Int16(nil, 1)) | ||
equal(t, int16(0), Int16(new(int16), 1)) | ||
equal(t, int16(16), Int16(&_int16, 2)) | ||
} | ||
|
||
func TestInt32(t *testing.T) { | ||
equal(t, int32(0), Int32(nil, 0)) | ||
equal(t, int32(1), Int32(nil, 1)) | ||
equal(t, int32(0), Int32(new(int32), 1)) | ||
equal(t, int32(32), Int32(&_int32, 2)) | ||
} | ||
|
||
func TestInt64(t *testing.T) { | ||
equal(t, int64(0), Int64(nil, 0)) | ||
equal(t, int64(1), Int64(nil, 1)) | ||
equal(t, int64(0), Int64(new(int64), 1)) | ||
equal(t, int64(64), Int64(&_int64, 2)) | ||
} | ||
|
||
func TestRune(t *testing.T) { | ||
equal(t, rune(0), Rune(nil, 0)) | ||
equal(t, rune(1), Rune(nil, 1)) | ||
equal(t, rune(0), Rune(new(rune), 1)) | ||
equal(t, rune(1), Rune(&_rune, 1)) | ||
} | ||
|
||
func TestString(t *testing.T) { | ||
equal(t, "", String(nil, "")) | ||
equal(t, "derefer", String(nil, "derefer")) | ||
equal(t, "", String(new(string), "derefed")) | ||
equal(t, "derefed", String(&_string, "derefer")) | ||
} | ||
|
||
func TestUint(t *testing.T) { | ||
equal(t, uint(0), Uint(nil, 0)) | ||
equal(t, uint(1), Uint(nil, 1)) | ||
equal(t, uint(0), Uint(new(uint), 1)) | ||
equal(t, uint(1), Uint(&_uint, 2)) | ||
} | ||
|
||
func TestUint8(t *testing.T) { | ||
equal(t, uint8(0), Uint8(nil, 0)) | ||
equal(t, uint8(1), Uint8(nil, 1)) | ||
equal(t, uint8(0), Uint8(new(uint8), 1)) | ||
equal(t, uint8(8), Uint8(&_uint8, 2)) | ||
} | ||
|
||
func TestUint16(t *testing.T) { | ||
equal(t, uint16(0), Uint16(nil, 0)) | ||
equal(t, uint16(1), Uint16(nil, 1)) | ||
equal(t, uint16(0), Uint16(new(uint16), 1)) | ||
equal(t, uint16(16), Uint16(&_uint16, 2)) | ||
} | ||
|
||
func TestUint32(t *testing.T) { | ||
equal(t, uint32(0), Uint32(nil, 0)) | ||
equal(t, uint32(1), Uint32(nil, 1)) | ||
equal(t, uint32(0), Uint32(new(uint32), 1)) | ||
equal(t, uint32(32), Uint32(&_uint32, 2)) | ||
} | ||
|
||
func TestUint64(t *testing.T) { | ||
equal(t, uint64(0), Uint64(nil, 0)) | ||
equal(t, uint64(1), Uint64(nil, 1)) | ||
equal(t, uint64(0), Uint64(new(uint64), 1)) | ||
equal(t, uint64(64), Uint64(&_uint64, 2)) | ||
} | ||
|
||
func TestUintptr(t *testing.T) { | ||
equal(t, uintptr(0), Uintptr(nil, 0)) | ||
equal(t, uintptr(1), Uintptr(nil, 1)) | ||
equal(t, uintptr(0), Uintptr(new(uintptr), 1)) | ||
equal(t, uintptr(64), Uintptr(&_uintptr, 2)) | ||
} |