├── .github ├── dependabot.yml └── workflows │ ├── codeql-analysis.yml │ └── test.yml ├── .gitignore ├── LICENSE ├── README.md ├── any.go ├── any_test.go ├── doc.go ├── example_any_test.go ├── example_test.go ├── go.mod ├── pointer.go ├── pointer_or_nil.go ├── pointer_or_nil_test.go ├── pointer_test.go ├── value.go ├── value_default.go ├── value_default_test.go └── value_test.go /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: gomod 9 | directory: "/" 10 | schedule: 11 | interval: daily 12 | 13 | # Maintain dependencies for GitHub Actions 14 | - package-ecosystem: "github-actions" 15 | directory: "/" 16 | schedule: 17 | interval: "daily" 18 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ main ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ main ] 20 | schedule: 21 | - cron: '32 12 * * 6' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'go' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v4 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v3 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | 52 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs 53 | # queries: security-extended,security-and-quality 54 | 55 | 56 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 57 | # If this step fails, then you should remove it and run the build manually (see below) 58 | - name: Autobuild 59 | uses: github/codeql-action/autobuild@v3 60 | 61 | # ℹ️ Command-line programs to run using the OS shell. 62 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun 63 | 64 | # If the Autobuild fails above, remove it and uncomment the following three lines. 65 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. 66 | 67 | # - run: | 68 | # echo "Run, Build Application using script" 69 | # ./location_of_script_within_repo/buildscript.sh 70 | 71 | - name: Perform CodeQL Analysis 72 | uses: github/codeql-action/analyze@v3 73 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: 4 | push: 5 | branches: main 6 | pull_request: 7 | 8 | jobs: 9 | test: 10 | runs-on: ubuntu-latest 11 | strategy: 12 | fail-fast: false 13 | matrix: 14 | go: 15 | - "1.24" 16 | - "1.23" 17 | - "1.22" 18 | - "1.21" 19 | - "1.20" 20 | - "1.19" 21 | - "1.18" 22 | - "1.17" 23 | steps: 24 | - uses: actions/checkout@v4 25 | - uses: actions/setup-go@v5 26 | with: 27 | go-version: "${{ matrix.go }}" 28 | - run: go test -v -coverprofile=profile.cov ./... 29 | - uses: shogo82148/actions-goveralls@v1 30 | with: 31 | path-to-profile: profile.cov 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Ichinose Shogo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pointer 2 | 3 | [![Go Reference](https://pkg.go.dev/badge/github.com/shogo82148/pointer.svg)](https://pkg.go.dev/github.com/shogo82148/pointer) 4 | ![test](https://github.com/shogo82148/pointer/workflows/test/badge.svg) 5 | 6 | Pointer Utility Functions for Golang. 7 | The Go's specification says that the operand of the address operation `&x` must be **addressable** 8 | (ref. https://golang.org/ref/spec#Address_operators ). 9 | It means that we can't get the addresses of [constants](https://golang.org/ref/spec#Constants), 10 | literals([Integer literals](https://golang.org/ref/spec#Integer_literals), [Floating-point literals](https://golang.org/ref/spec#Floating-point_literals), 11 | [String literals](https://golang.org/ref/spec#String_literals), etc.), and the return values of a function or method. 12 | The `pointer` package makes them addressable, and returns their pointers. 13 | 14 | ## SYNOPSIS 15 | 16 | ```go 17 | import "github.com/shogo82148/pointer" 18 | 19 | type Stuff struct { 20 | Name *string 21 | Comment *string 22 | Value *int64 23 | Time *time.Time 24 | } 25 | 26 | func main() { 27 | const defaultName = "some name" 28 | 29 | // convert to pointers 30 | stuff := &Stuff{ 31 | // it is same as s := defaultName; &s 32 | // can't be &defaultName 33 | Name: pointer.String(defaultName), 34 | 35 | // can't be &"not yet" 36 | Comment: pointer.String("not yet"), 37 | 38 | // can't be &42 or &int64(42) 39 | Value: pointer.Int64(42), 40 | 41 | // can't be &time.Date(2014, 6, 25, 12, 24, 40, 0, time.UTC) 42 | Time: pointer.Time(time.Date(2014, 6, 25, 12, 24, 40, 0, time.UTC)), 43 | } 44 | 45 | // Int64OrNil(v) is like Int64, but it returns nil if v is the zero value. 46 | stuff.Value = pointer.Int64OrNil(0) 47 | 48 | // StringValue(p) is like *p but it returns "" if p is nil 49 | // It never panic. 50 | fmt.Printf("%s\n", pointer.StringValue(stuff.Name)) 51 | 52 | // StringValueWithDefault returns the default value if p is nil 53 | fmt.Printf("%s\n", pointer.StringValueWithDefault(stuff.Name, "John")) 54 | 55 | // From Go 1.18, generics functions are supported. 56 | stuff.Value = pointer.Ptr(int64(42)) // same as pointer.Int64 57 | stuff.Value = pointer.PtrOrNil(int64(0)) // same as pointer.Int64OrNil 58 | fmt.Printf("%s\n", pointer.Value(stuff.Name)) // same as pointer.StringValue 59 | fmt.Printf("%s\n", pointer.ValueWithDefault(stuff.Name, "John")) // same as pointer.StringValueWithDefault 60 | } 61 | ``` 62 | 63 | ## RELATED WORKS 64 | 65 | - https://github.com/AlekSi/pointer 66 | - https://github.com/agrea/ptr 67 | -------------------------------------------------------------------------------- /any.go: -------------------------------------------------------------------------------- 1 | //go:build go1.18 2 | // +build go1.18 3 | 4 | package pointer 5 | 6 | // Ptr returns a pointer whose value is v. 7 | func Ptr[T any](v T) *T { 8 | return &v 9 | } 10 | 11 | // PtrOrNil is like Any but returns nil if v is the zero value. 12 | func PtrOrNil[T comparable](v T) *T { 13 | if v == Zero[T]() { 14 | return nil 15 | } 16 | return &v 17 | } 18 | 19 | // ValueWithDefault is like *p but it returns def if p is nil. 20 | func ValueWithDefault[T any](p *T, def T) T { 21 | if p == nil { 22 | return def 23 | } 24 | return *p 25 | } 26 | 27 | // Value is like *p but it returns the zero value if p is nil. 28 | func Value[T any](p *T) T { 29 | if p == nil { 30 | return Zero[T]() 31 | } 32 | return *p 33 | } 34 | 35 | // Equal returns *a == *b but it also accepts nil pointers. 36 | // Special cases are: 37 | // 38 | // Equal(nil, nil) = true 39 | // Equal(nil, &v) = false 40 | // Equal(&v, nil) = false 41 | func Equal[T comparable](a, b *T) bool { 42 | return a == b || (a != nil && b != nil && *a == *b) 43 | } 44 | 45 | // ShallowCopy returns a shallow copy of v. 46 | // If v is nil, it returns a nil pointer. 47 | func ShallowCopy[T any](v *T) *T { 48 | if v == nil { 49 | return nil 50 | } 51 | u := *v 52 | return &u 53 | } 54 | 55 | // Zero returns the zero value of type T. 56 | func Zero[T any]() T { 57 | var zero T 58 | return zero 59 | } 60 | -------------------------------------------------------------------------------- /any_test.go: -------------------------------------------------------------------------------- 1 | //go:build go1.18 2 | // +build go1.18 3 | 4 | package pointer 5 | 6 | import ( 7 | "testing" 8 | "time" 9 | ) 10 | 11 | func TestAnyPtr(t *testing.T) { 12 | if v := Ptr(42); *v != 42 { 13 | t.Errorf("want %d, got %d", 42, *v) 14 | } 15 | 16 | if v := Ptr("foo"); *v != "foo" { 17 | t.Errorf("want %q, got %q", "foo", *v) 18 | } 19 | 20 | if v := Ptr(42.0); *v != 42.0 { 21 | t.Errorf("want %f, got %f", 42.0, *v) 22 | } 23 | 24 | if v := Ptr(true); *v != true { 25 | t.Errorf("want %t, got %t", true, *v) 26 | } 27 | 28 | if v := Ptr(time.Date(2020, time.January, 17, 2, 19, 0, 0, time.UTC)); !v.Equal(time.Date(2020, time.January, 17, 2, 19, 0, 0, time.UTC)) { 29 | t.Errorf("want %s, got %s", time.Date(2020, time.January, 17, 2, 19, 0, 0, time.UTC), v) 30 | } 31 | } 32 | func TestAnyPtrOrNil(t *testing.T) { 33 | if v := PtrOrNil(42); *v != 42 { 34 | t.Errorf("want %d, got %d", 42, *v) 35 | } 36 | 37 | if v := PtrOrNil("foo"); *v != "foo" { 38 | t.Errorf("want %q, got %q", "foo", *v) 39 | } 40 | 41 | if v := PtrOrNil(42.0); *v != 42.0 { 42 | t.Errorf("want %f, got %f", 42.0, *v) 43 | } 44 | 45 | if v := PtrOrNil(true); *v != true { 46 | t.Errorf("want %t, got %t", true, *v) 47 | } 48 | 49 | if v := PtrOrNil(time.Date(2020, time.January, 17, 2, 19, 0, 0, time.UTC)); !v.Equal(time.Date(2020, time.January, 17, 2, 19, 0, 0, time.UTC)) { 50 | t.Errorf("want %s, got %s", time.Date(2020, time.January, 17, 2, 19, 0, 0, time.UTC), v) 51 | } 52 | 53 | if v := PtrOrNil(0); v != nil { 54 | t.Errorf("want nil, got %p", v) 55 | } 56 | 57 | if v := PtrOrNil(""); v != nil { 58 | t.Errorf("want nil, got %p", v) 59 | } 60 | 61 | if v := PtrOrNil(0.0); v != nil { 62 | t.Errorf("want nil, got %p", v) 63 | } 64 | 65 | if v := PtrOrNil(false); v != nil { 66 | t.Errorf("want nil, got %p", v) 67 | } 68 | 69 | if v := PtrOrNil(time.Time{}); v != nil { 70 | t.Errorf("want nil, got %p", v) 71 | } 72 | } 73 | 74 | func TestValueWithDefault(t *testing.T) { 75 | var v int = 42 76 | var got int 77 | 78 | got = ValueWithDefault(&v, 0) 79 | if got != 42 { 80 | t.Errorf("want %d, got %d", 42, got) 81 | } 82 | 83 | got = ValueWithDefault(nil, 42) 84 | if got != 42 { 85 | t.Errorf("want %d, got %d", 42, got) 86 | } 87 | } 88 | 89 | func TestValue(t *testing.T) { 90 | var v int = 42 91 | var got int 92 | 93 | got = Value(&v) 94 | if got != 42 { 95 | t.Errorf("want %d, got %d", 42, got) 96 | } 97 | 98 | got = Value((*int)(nil)) 99 | if got != 0 { 100 | t.Errorf("want %d, got %d", 0, got) 101 | } 102 | } 103 | 104 | func TestEqual(t *testing.T) { 105 | var v int 106 | 107 | // a == b 108 | if !Equal(&v, &v) { 109 | t.Error("Equal(&v, &v) should be true, got false") 110 | } 111 | 112 | // a != b but *a == *b 113 | if !Equal(&v, Ptr(0)) { 114 | t.Error("should be true, got false") 115 | } 116 | 117 | a := [...]int{1, 2, 3} 118 | b := [...]int{1, 2, 3} 119 | if !Equal(&a, &b) { 120 | t.Error("should be true, got false") 121 | } 122 | 123 | if Equal(nil, &v) { 124 | t.Error("Equal(nil, &v) should be false, got true") 125 | } 126 | 127 | if Equal(&v, nil) { 128 | t.Error("Equal(&v, nil) should be false, got true") 129 | } 130 | 131 | if !Equal((*int)(nil), (*int)(nil)) { 132 | t.Error("Equal((*int)(nil), (*int)(nil)) should be true, got false") 133 | } 134 | } 135 | 136 | func TestShallowCopy(t *testing.T) { 137 | v := &struct { 138 | Foo int 139 | Bar int 140 | }{42, 46} 141 | u := ShallowCopy(v) 142 | 143 | if u == v { 144 | t.Errorf("should not equal u and v: u = %p, v = %p", u, v) 145 | } 146 | if !Equal(u, v) { 147 | t.Errorf("*u and *v should be same value, but u = %#v, v = %#v", u, v) 148 | } 149 | 150 | v.Foo++ 151 | if u.Foo != 42 { 152 | t.Errorf("u should not be changed, but u.Foo is %d", u.Foo) 153 | } 154 | 155 | // in case of nil pointer 156 | v = nil 157 | u = ShallowCopy(v) 158 | if u != nil { 159 | t.Errorf("want nil pointer, got %p", u) 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package pointer provides pointer utility functions. 3 | 4 | The Go's specification says that the operand of the address operation &x must be addressable 5 | (ref. https://golang.org/ref/spec#Address_operators ). 6 | It means that we cat get the addresses of constants, literals(Integer literals, Floating-point literals, 7 | String literals, etc.), and the return values of a function or method. 8 | The pointer packages make them addressable, and returns their pointers. 9 | 10 | import "github.com/shogo82148/pointer" 11 | 12 | type Stuff struct { 13 | Name *string 14 | Comment *string 15 | Value *int64 16 | Time *time.Time 17 | } 18 | 19 | func main() { 20 | const defaultName = "some name" 21 | 22 | // convert to pointers 23 | stuff := &Stuff{ 24 | // it is same as s := defaultName; &s 25 | // can't be &defaultName 26 | Name: pointer.String(defaultName), 27 | 28 | // can't be &"not yet" 29 | Comment: pointer.String("not yet"), 30 | 31 | // can't be &42 or &int64(42) 32 | Value: pointer.Int64(42), 33 | 34 | // can't be &time.Date(2014, 6, 25, 12, 24, 40, 0, time.UTC) 35 | Time: pointer.Time(time.Date(2014, 6, 25, 12, 24, 40, 0, time.UTC)), 36 | } 37 | 38 | // Int64OrNil(v) is like Int64, but it returns nil if v is the zero value. 39 | stuff.Value = pointer.Int64OrNil(0) 40 | 41 | // StringValue(p) is like *p but it returns "" if p is nil 42 | // It never panic. 43 | fmt.Printf("%s\n", pointer.StringValue(stuff.Name)) 44 | 45 | // StringValueWithDefault returns the default value if p is nil 46 | fmt.Printf("%s\n", pointer.StringValueWithDefault(stuff.Name, "John")) 47 | 48 | // From Go 1.18, generics functions are supported. 49 | stuff.Value = pointer.Ptr(int64(42)) // same as pointer.Int64 50 | stuff.Value = pointer.PtrOrNil(int64(0)) // same as pointer.Int64OrNil 51 | fmt.Printf("%s\n", pointer.Value(stuff.Name)) // same as pointer.StringValue 52 | fmt.Printf("%s\n", pointer.ValueWithDefault(stuff.Name, "John")) // same as pointer.StringValueWithDefault 53 | } 54 | */ 55 | package pointer 56 | -------------------------------------------------------------------------------- /example_any_test.go: -------------------------------------------------------------------------------- 1 | //go:build go1.18 2 | // +build go1.18 3 | 4 | package pointer_test 5 | 6 | import ( 7 | "fmt" 8 | 9 | "github.com/shogo82148/pointer" 10 | ) 11 | 12 | func ExamplePtr() { 13 | v := pointer.Ptr(42) 14 | fmt.Printf("%d\n", *v) 15 | 16 | //Output: 17 | // 42 18 | } 19 | 20 | func ExamplePtrOrNil() { 21 | v := pointer.PtrOrNil(42) 22 | fmt.Printf("%d\n", *v) 23 | 24 | v = pointer.PtrOrNil(0) 25 | fmt.Printf("%t\n", v == nil) 26 | 27 | //Output: 28 | // 42 29 | // true 30 | } 31 | 32 | func ExampleValue() { 33 | v := pointer.Ptr(42) 34 | fmt.Printf("%d\n", pointer.Value(v)) 35 | 36 | v = nil 37 | fmt.Printf("%d\n", pointer.Value(v)) 38 | 39 | //Output: 40 | // 42 41 | // 0 42 | } 43 | 44 | func ExampleEqual() { 45 | // a and b have the same look. 46 | a := pointer.Ptr(42) 47 | b := pointer.Ptr(42) 48 | 49 | // But it reports false because a and b have differrent addresses. 50 | fmt.Printf("a == b: %t\n", a == b) 51 | 52 | // Equal returns true. 53 | fmt.Printf("pointer.Equal(a, b): %t\n", pointer.Equal(a, b)) 54 | 55 | //Output: 56 | // a == b: false 57 | // pointer.Equal(a, b): true 58 | } 59 | -------------------------------------------------------------------------------- /example_test.go: -------------------------------------------------------------------------------- 1 | package pointer_test 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/shogo82148/pointer" 7 | ) 8 | 9 | func ExampleInt() { 10 | v := pointer.Int(42) 11 | fmt.Printf("%d\n", *v) 12 | 13 | //Output: 14 | // 42 15 | } 16 | 17 | func ExampleIntOrNil() { 18 | v := pointer.IntOrNil(42) 19 | fmt.Printf("%d\n", *v) 20 | 21 | v = pointer.IntOrNil(0) 22 | fmt.Printf("%t\n", v == nil) 23 | 24 | //Output: 25 | // 42 26 | // true 27 | } 28 | 29 | func ExampleIntValue() { 30 | v := pointer.Int(42) 31 | fmt.Printf("%d\n", pointer.IntValue(v)) 32 | fmt.Printf("%d\n", pointer.IntValue(nil)) 33 | 34 | //Output: 35 | // 42 36 | // 0 37 | } 38 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/shogo82148/pointer 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /pointer.go: -------------------------------------------------------------------------------- 1 | package pointer 2 | 3 | import "time" 4 | 5 | // Int returns a pointer to an int whose value is v. 6 | func Int(v int) *int { 7 | return &v 8 | } 9 | 10 | // Int8 returns a pointer to an int8 whose value is v. 11 | func Int8(v int8) *int8 { 12 | return &v 13 | } 14 | 15 | // Int16 returns a pointer to an int16 whose value is v. 16 | func Int16(v int16) *int16 { 17 | return &v 18 | } 19 | 20 | // Int32 returns a pointer to an int32 whose value is v. 21 | func Int32(v int32) *int32 { 22 | return &v 23 | } 24 | 25 | // Int64 returns a pointer to an int64 whose value is v. 26 | func Int64(v int64) *int64 { 27 | return &v 28 | } 29 | 30 | // Uint returns a pointer to an uint whose value is v. 31 | func Uint(v int) *int { 32 | return &v 33 | } 34 | 35 | // Uint8 returns a pointer to an uint8 whose value is v. 36 | func Uint8(v uint8) *uint8 { 37 | return &v 38 | } 39 | 40 | // Uint16 returns a pointer to an uint16 whose value is v. 41 | func Uint16(v uint16) *uint16 { 42 | return &v 43 | } 44 | 45 | // Uint32 returns a pointer to an uint32 whose value is v. 46 | func Uint32(v uint32) *uint32 { 47 | return &v 48 | } 49 | 50 | // Uint64 returns a pointer to an uint64 whose value is v. 51 | func Uint64(v uint64) *uint64 { 52 | return &v 53 | } 54 | 55 | // String returns a pointer to a string whose value is v. 56 | func String(v string) *string { 57 | return &v 58 | } 59 | 60 | // Float32 returns a pointer to a string whose value is v. 61 | func Float32(v float32) *float32 { 62 | return &v 63 | } 64 | 65 | // Float64 returns a pointer to a string whose value is v. 66 | func Float64(v float64) *float64 { 67 | return &v 68 | } 69 | 70 | // Bool returns a pointer to a string whose value is v. 71 | func Bool(v bool) *bool { 72 | return &v 73 | } 74 | 75 | // Byte returns a pointer to a byte whose value is v. 76 | func Byte(v byte) *byte { 77 | return &v 78 | } 79 | 80 | // Rune returns a pointer to a rune whose value is v. 81 | func Rune(v rune) *rune { 82 | return &v 83 | } 84 | 85 | // Time returns a pointer to a time.Time whose value is v. 86 | func Time(v time.Time) *time.Time { 87 | return &v 88 | } 89 | 90 | // Complex64 returns a pointer to a complex64 whose value is v. 91 | func Complex64(v complex64) *complex64 { 92 | return &v 93 | } 94 | 95 | // Complex128 returns a pointer to a complex128 whose value is v. 96 | func Complex128(v complex128) *complex128 { 97 | return &v 98 | } 99 | -------------------------------------------------------------------------------- /pointer_or_nil.go: -------------------------------------------------------------------------------- 1 | package pointer 2 | 3 | import "time" 4 | 5 | // IntOrNil is like Int but returns nil if v is 0. 6 | func IntOrNil(v int) *int { 7 | if v == 0 { 8 | return nil 9 | } 10 | return &v 11 | } 12 | 13 | // Int8OrNil is like Int8 but returns nil if v is 0. 14 | func Int8OrNil(v int8) *int8 { 15 | if v == 0 { 16 | return nil 17 | } 18 | return &v 19 | } 20 | 21 | // Int16OrNil is like Int but returns nil if v is 0. 22 | func Int16OrNil(v int16) *int16 { 23 | if v == 0 { 24 | return nil 25 | } 26 | return &v 27 | } 28 | 29 | // Int32OrNil is like Int32 but returns nil if v is 0. 30 | func Int32OrNil(v int32) *int32 { 31 | if v == 0 { 32 | return nil 33 | } 34 | return &v 35 | } 36 | 37 | // Int64OrNil is like Int64 but returns nil if v is 0. 38 | func Int64OrNil(v int64) *int64 { 39 | if v == 0 { 40 | return nil 41 | } 42 | return &v 43 | } 44 | 45 | // UintOrNil is like Uint but returns nil if v is 0. 46 | func UintOrNil(v uint) *uint { 47 | if v == 0 { 48 | return nil 49 | } 50 | return &v 51 | } 52 | 53 | // Uint8OrNil is like Uint8 but returns nil if v is 0. 54 | func Uint8OrNil(v uint8) *uint8 { 55 | if v == 0 { 56 | return nil 57 | } 58 | return &v 59 | } 60 | 61 | // Uint16OrNil is like Uint16 but returns nil if v is 0. 62 | func Uint16OrNil(v uint16) *uint16 { 63 | if v == 0 { 64 | return nil 65 | } 66 | return &v 67 | } 68 | 69 | // Uint32OrNil is like Uint32 but returns nil if v is 0. 70 | func Uint32OrNil(v uint32) *uint32 { 71 | if v == 0 { 72 | return nil 73 | } 74 | return &v 75 | } 76 | 77 | // Uint64OrNil is like Uint64 but returns nil if v is 0. 78 | func Uint64OrNil(v uint64) *uint64 { 79 | if v == 0 { 80 | return nil 81 | } 82 | return &v 83 | } 84 | 85 | // StringOrNil is like String but returns nil if v is "". 86 | func StringOrNil(v string) *string { 87 | if v == "" { 88 | return nil 89 | } 90 | return &v 91 | } 92 | 93 | // Float32OrNil is like Float32 but returns nil if v is 0. 94 | func Float32OrNil(v float32) *float32 { 95 | if v == 0 { 96 | return nil 97 | } 98 | return &v 99 | } 100 | 101 | // Float64OrNil is like Float64 but returns nil if v is 0. 102 | func Float64OrNil(v float64) *float64 { 103 | if v == 0 { 104 | return nil 105 | } 106 | return &v 107 | } 108 | 109 | // BoolOrNil is like Int but returns nil if v is 0. 110 | func BoolOrNil(v bool) *bool { 111 | if !v { 112 | return nil 113 | } 114 | return &v 115 | } 116 | 117 | // ByteOrNil is like Byte but returns nil if v is 0. 118 | func ByteOrNil(v byte) *byte { 119 | if v == 0 { 120 | return nil 121 | } 122 | return &v 123 | } 124 | 125 | // RuneOrNil is like Byte but returns nil if v is 0. 126 | func RuneOrNil(v rune) *rune { 127 | if v == 0 { 128 | return nil 129 | } 130 | return &v 131 | } 132 | 133 | // TimeOrNil is like Time but returns nil if v is the zero value of time.Time. 134 | func TimeOrNil(v time.Time) *time.Time { 135 | if v.IsZero() { 136 | return nil 137 | } 138 | return &v 139 | } 140 | -------------------------------------------------------------------------------- /pointer_or_nil_test.go: -------------------------------------------------------------------------------- 1 | package pointer 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func TestPointerOrNil(t *testing.T) { 9 | if v := IntOrNil(42); *v != 42 { 10 | t.Errorf("want %d, got %d", 42, *v) 11 | } 12 | 13 | if v := Int8OrNil(42); *v != 42 { 14 | t.Errorf("want %d, got %d", 42, *v) 15 | } 16 | 17 | if v := Int16OrNil(42); *v != 42 { 18 | t.Errorf("want %d, got %d", 42, *v) 19 | } 20 | 21 | if v := Int32OrNil(42); *v != 42 { 22 | t.Errorf("want %d, got %d", 42, *v) 23 | } 24 | 25 | if v := Int64OrNil(42); *v != 42 { 26 | t.Errorf("want %d, got %d", 42, *v) 27 | } 28 | 29 | if v := UintOrNil(42); *v != 42 { 30 | t.Errorf("want %d, got %d", 42, *v) 31 | } 32 | 33 | if v := Uint8OrNil(42); *v != 42 { 34 | t.Errorf("want %d, got %d", 42, *v) 35 | } 36 | 37 | if v := Uint16OrNil(42); *v != 42 { 38 | t.Errorf("want %d, got %d", 42, *v) 39 | } 40 | 41 | if v := Uint32OrNil(42); *v != 42 { 42 | t.Errorf("want %d, got %d", 42, *v) 43 | } 44 | 45 | if v := Uint64OrNil(42); *v != 42 { 46 | t.Errorf("want %d, got %d", 42, *v) 47 | } 48 | 49 | if v := StringOrNil("foo"); *v != "foo" { 50 | t.Errorf("want %q, got %q", "foo", *v) 51 | } 52 | 53 | if v := Float32OrNil(42); *v != 42.0 { 54 | t.Errorf("want %f, got %f", 42.0, *v) 55 | } 56 | 57 | if v := Float64OrNil(42); *v != 42.0 { 58 | t.Errorf("want %f, got %f", 42.0, *v) 59 | } 60 | 61 | if v := BoolOrNil(true); *v != true { 62 | t.Errorf("want %t, got %t", true, *v) 63 | } 64 | 65 | if v := ByteOrNil(42); *v != 42 { 66 | t.Errorf("want %d, got %d", 42, *v) 67 | } 68 | 69 | if v := RuneOrNil('a'); *v != 'a' { 70 | t.Errorf("want %c, got %c", 'a', *v) 71 | } 72 | 73 | if v := TimeOrNil(time.Date(2020, time.January, 17, 2, 19, 0, 0, time.UTC)); !v.Equal(time.Date(2020, time.January, 17, 2, 19, 0, 0, time.UTC)) { 74 | t.Errorf("want %s, got %s", time.Date(2020, time.January, 17, 2, 19, 0, 0, time.UTC), v) 75 | } 76 | 77 | if v := IntOrNil(0); v != nil { 78 | t.Errorf("want nil, got %p", v) 79 | } 80 | 81 | if v := Int8OrNil(0); v != nil { 82 | t.Errorf("want nil, got %p", v) 83 | } 84 | 85 | if v := Int16OrNil(0); v != nil { 86 | t.Errorf("want nil, got %p", v) 87 | } 88 | 89 | if v := Int32OrNil(0); v != nil { 90 | t.Errorf("want nil, got %p", v) 91 | } 92 | 93 | if v := Int64OrNil(0); v != nil { 94 | t.Errorf("want nil, got %p", v) 95 | } 96 | 97 | if v := UintOrNil(0); v != nil { 98 | t.Errorf("want nil, got %p", v) 99 | } 100 | 101 | if v := Uint8OrNil(0); v != nil { 102 | t.Errorf("want nil, got %p", v) 103 | } 104 | 105 | if v := Uint16OrNil(0); v != nil { 106 | t.Errorf("want nil, got %p", v) 107 | } 108 | 109 | if v := Uint32OrNil(0); v != nil { 110 | t.Errorf("want nil, got %p", v) 111 | } 112 | 113 | if v := Uint64OrNil(0); v != nil { 114 | t.Errorf("want nil, got %p", v) 115 | } 116 | 117 | if v := StringOrNil(""); v != nil { 118 | t.Errorf("want nil, got %p", v) 119 | } 120 | 121 | if v := Float32OrNil(0); v != nil { 122 | t.Errorf("want nil, got %p", v) 123 | } 124 | 125 | if v := Float64OrNil(0); v != nil { 126 | t.Errorf("want nil, got %p", v) 127 | } 128 | 129 | if v := BoolOrNil(false); v != nil { 130 | t.Errorf("want nil, got %p", v) 131 | } 132 | 133 | if v := ByteOrNil(0); v != nil { 134 | t.Errorf("want nil, got %p", v) 135 | } 136 | 137 | if v := RuneOrNil(0); v != nil { 138 | t.Errorf("want nil, got %p", v) 139 | } 140 | 141 | if v := TimeOrNil(time.Time{}); v != nil { 142 | t.Errorf("want nil, got %p", v) 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /pointer_test.go: -------------------------------------------------------------------------------- 1 | package pointer 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func TestPointer(t *testing.T) { 9 | if v := Int(42); *v != 42 { 10 | t.Errorf("want %d, got %d", 42, *v) 11 | } 12 | 13 | if v := Int8(42); *v != 42 { 14 | t.Errorf("want %d, got %d", 42, *v) 15 | } 16 | 17 | if v := Int16(42); *v != 42 { 18 | t.Errorf("want %d, got %d", 42, *v) 19 | } 20 | 21 | if v := Int32(42); *v != 42 { 22 | t.Errorf("want %d, got %d", 42, *v) 23 | } 24 | 25 | if v := Int64(42); *v != 42 { 26 | t.Errorf("want %d, got %d", 42, *v) 27 | } 28 | 29 | if v := Uint(42); *v != 42 { 30 | t.Errorf("want %d, got %d", 42, *v) 31 | } 32 | 33 | if v := Uint8(42); *v != 42 { 34 | t.Errorf("want %d, got %d", 42, *v) 35 | } 36 | 37 | if v := Uint16(42); *v != 42 { 38 | t.Errorf("want %d, got %d", 42, *v) 39 | } 40 | 41 | if v := Uint32(42); *v != 42 { 42 | t.Errorf("want %d, got %d", 42, *v) 43 | } 44 | 45 | if v := Uint64(42); *v != 42 { 46 | t.Errorf("want %d, got %d", 42, *v) 47 | } 48 | 49 | if v := String("foo"); *v != "foo" { 50 | t.Errorf("want %q, got %q", "foo", *v) 51 | } 52 | 53 | if v := Float32(42); *v != 42.0 { 54 | t.Errorf("want %f, got %f", 42.0, *v) 55 | } 56 | 57 | if v := Float64(42); *v != 42.0 { 58 | t.Errorf("want %f, got %f", 42.0, *v) 59 | } 60 | 61 | if v := Bool(true); *v != true { 62 | t.Errorf("want %t, got %t", true, *v) 63 | } 64 | 65 | if v := Byte(42); *v != 42 { 66 | t.Errorf("want %d, got %d", 42, *v) 67 | } 68 | 69 | if v := Rune('a'); *v != 'a' { 70 | t.Errorf("want %c, got %c", 'a', *v) 71 | } 72 | 73 | if v := Time(time.Date(2020, time.January, 17, 2, 19, 0, 0, time.UTC)); !v.Equal(time.Date(2020, time.January, 17, 2, 19, 0, 0, time.UTC)) { 74 | t.Errorf("want %s, got %s", time.Date(2020, time.January, 17, 2, 19, 0, 0, time.UTC), v) 75 | } 76 | 77 | if v := Complex64(1 + 2i); *v != 1+2i { 78 | t.Errorf("want %f, got %f", 1+2i, *v) 79 | } 80 | 81 | if v := Complex128(1 + 2i); *v != 1+2i { 82 | t.Errorf("want %f, got %f", 1+2i, *v) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /value.go: -------------------------------------------------------------------------------- 1 | package pointer 2 | 3 | import "time" 4 | 5 | // IntValue is like *p but it returns 0 if p is nil. 6 | func IntValue(p *int) int { 7 | if p == nil { 8 | return 0 9 | } 10 | return *p 11 | } 12 | 13 | // Int8Value is like *p but it returns 0 if p is nil. 14 | func Int8Value(p *int8) int8 { 15 | if p == nil { 16 | return 0 17 | } 18 | return *p 19 | } 20 | 21 | // Int16Value is like *p but it returns 0 if p is nil. 22 | func Int16Value(p *int16) int16 { 23 | if p == nil { 24 | return 0 25 | } 26 | return *p 27 | } 28 | 29 | // Int32Value is like *p but it returns 0 if p is nil. 30 | func Int32Value(p *int32) int32 { 31 | if p == nil { 32 | return 0 33 | } 34 | return *p 35 | } 36 | 37 | // Int64Value is like *p but it returns 0 if p is nil. 38 | func Int64Value(p *int64) int64 { 39 | if p == nil { 40 | return 0 41 | } 42 | return *p 43 | } 44 | 45 | // UintValue is like *p but it returns 0 if p is nil. 46 | func UintValue(p *uint) uint { 47 | if p == nil { 48 | return 0 49 | } 50 | return *p 51 | } 52 | 53 | // Uint8Value is like *p but it returns 0 if p is nil. 54 | func Uint8Value(p *uint8) uint8 { 55 | if p == nil { 56 | return 0 57 | } 58 | return *p 59 | } 60 | 61 | // Uint16Value is like *p but it returns 0 if p is nil. 62 | func Uint16Value(p *uint16) uint16 { 63 | if p == nil { 64 | return 0 65 | } 66 | return *p 67 | } 68 | 69 | // Uint32Value is like *p but it returns 0 if p is nil. 70 | func Uint32Value(p *uint32) uint32 { 71 | if p == nil { 72 | return 0 73 | } 74 | return *p 75 | } 76 | 77 | // Uint64Value is like *p but it returns 0 if p is nil. 78 | func Uint64Value(p *uint64) uint64 { 79 | if p == nil { 80 | return 0 81 | } 82 | return *p 83 | } 84 | 85 | // StringValue is like *p but it returns "" if p is nil. 86 | func StringValue(p *string) string { 87 | if p == nil { 88 | return "" 89 | } 90 | return *p 91 | } 92 | 93 | // Float32Value is like *p but it returns 0 if p is nil. 94 | func Float32Value(p *float32) float32 { 95 | if p == nil { 96 | return 0 97 | } 98 | return *p 99 | } 100 | 101 | // Float64Value is like *p but it returns 0 if p is nil. 102 | func Float64Value(p *float64) float64 { 103 | if p == nil { 104 | return 0 105 | } 106 | return *p 107 | } 108 | 109 | // BoolValue is like *p but it returns false if p is nil. 110 | func BoolValue(p *bool) bool { 111 | if p == nil { 112 | return false 113 | } 114 | return *p 115 | } 116 | 117 | // ByteValue is like *p but it returns 0 if p is nil. 118 | func ByteValue(p *byte) byte { 119 | if p == nil { 120 | return 0 121 | } 122 | return *p 123 | } 124 | 125 | // RuneValue is like *p but it returns 0 if p is nil. 126 | func RuneValue(p *rune) rune { 127 | if p == nil { 128 | return 0 129 | } 130 | return *p 131 | } 132 | 133 | // TimeValue is like *p but it returns time.Time{} if p is nil. 134 | func TimeValue(p *time.Time) time.Time { 135 | if p == nil { 136 | return time.Time{} 137 | } 138 | return *p 139 | } 140 | 141 | // Complex64Value is like *p but it returns 0 if p is nil. 142 | func Complex64Value(p *complex64) complex64 { 143 | if p == nil { 144 | return 0 145 | } 146 | return *p 147 | } 148 | 149 | // Complex128Value is like *p but it returns 0 if p is nil. 150 | func Complex128Value(p *complex128) complex128 { 151 | if p == nil { 152 | return 0 153 | } 154 | return *p 155 | } 156 | -------------------------------------------------------------------------------- /value_default.go: -------------------------------------------------------------------------------- 1 | package pointer 2 | 3 | import "time" 4 | 5 | // IntValueWithDefault is like *p but it returns def if p is nil. 6 | func IntValueWithDefault(p *int, def int) int { 7 | if p == nil { 8 | return def 9 | } 10 | return *p 11 | } 12 | 13 | // Int8ValueWithDefault is like *p but it returns def if p is nil. 14 | func Int8ValueWithDefault(p *int8, def int8) int8 { 15 | if p == nil { 16 | return def 17 | } 18 | return *p 19 | } 20 | 21 | // Int16ValueWithDefault is like *p but it returns def if p is nil. 22 | func Int16ValueWithDefault(p *int16, def int16) int16 { 23 | if p == nil { 24 | return def 25 | } 26 | return *p 27 | } 28 | 29 | // Int32ValueWithDefault is like *p but it returns def if p is nil. 30 | func Int32ValueWithDefault(p *int32, def int32) int32 { 31 | if p == nil { 32 | return def 33 | } 34 | return *p 35 | } 36 | 37 | // Int64ValueWithDefault is like *p but it returns def if p is nil. 38 | func Int64ValueWithDefault(p *int64, def int64) int64 { 39 | if p == nil { 40 | return def 41 | } 42 | return *p 43 | } 44 | 45 | // UintValueWithDefault is like *p but it returns def if p is nil. 46 | func UintValueWithDefault(p *uint, def uint) uint { 47 | if p == nil { 48 | return def 49 | } 50 | return *p 51 | } 52 | 53 | // Uint8ValueWithDefault is like *p but it returns def if p is nil. 54 | func Uint8ValueWithDefault(p *uint8, def uint8) uint8 { 55 | if p == nil { 56 | return def 57 | } 58 | return *p 59 | } 60 | 61 | // Uint16ValueWithDefault is like *p but it returns def if p is nil. 62 | func Uint16ValueWithDefault(p *uint16, def uint16) uint16 { 63 | if p == nil { 64 | return def 65 | } 66 | return *p 67 | } 68 | 69 | // Uint32ValueWithDefault is like *p but it returns def if p is nil. 70 | func Uint32ValueWithDefault(p *uint32, def uint32) uint32 { 71 | if p == nil { 72 | return def 73 | } 74 | return *p 75 | } 76 | 77 | // Uint64ValueWithDefault is like *p but it returns def if p is nil. 78 | func Uint64ValueWithDefault(p *uint64, def uint64) uint64 { 79 | if p == nil { 80 | return def 81 | } 82 | return *p 83 | } 84 | 85 | // StringValueWithDefault is like *p but it returns def if p is nil. 86 | func StringValueWithDefault(p *string, def string) string { 87 | if p == nil { 88 | return def 89 | } 90 | return *p 91 | } 92 | 93 | // Float32ValueWithDefault is like *p but it returns def if p is nil. 94 | func Float32ValueWithDefault(p *float32, def float32) float32 { 95 | if p == nil { 96 | return def 97 | } 98 | return *p 99 | } 100 | 101 | // Float64ValueWithDefault is like *p but it returns def if p is nil. 102 | func Float64ValueWithDefault(p *float64, def float64) float64 { 103 | if p == nil { 104 | return def 105 | } 106 | return *p 107 | } 108 | 109 | // BoolValueWithDefault is like *p but it returns def if p is nil. 110 | func BoolValueWithDefault(p *bool, def bool) bool { 111 | if p == nil { 112 | return def 113 | } 114 | return *p 115 | } 116 | 117 | // ByteValueWithDefault is like *p but it returns def if p is nil. 118 | func ByteValueWithDefault(p *byte, def byte) byte { 119 | if p == nil { 120 | return def 121 | } 122 | return *p 123 | } 124 | 125 | // RuneValueWithDefault is like *p but it returns def if p is nil. 126 | func RuneValueWithDefault(p *rune, def rune) rune { 127 | if p == nil { 128 | return def 129 | } 130 | return *p 131 | } 132 | 133 | // TimeValueWithDefault is like *p but it returns def if p is nil. 134 | func TimeValueWithDefault(p *time.Time, def time.Time) time.Time { 135 | if p == nil { 136 | return def 137 | } 138 | return *p 139 | } 140 | 141 | // Complex64ValueWithDefault is like *p but it returns def if p is nil. 142 | func Complex64ValueWithDefault(p *complex64, def complex64) complex64 { 143 | if p == nil { 144 | return def 145 | } 146 | return *p 147 | } 148 | 149 | // Complex128ValueWithDefault is like *p but it returns def if p is nil. 150 | func Complex128ValueWithDefault(p *complex128, def complex128) complex128 { 151 | if p == nil { 152 | return def 153 | } 154 | return *p 155 | } 156 | -------------------------------------------------------------------------------- /value_default_test.go: -------------------------------------------------------------------------------- 1 | package pointer 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func TestIntValueWithDefault(t *testing.T) { 9 | var v int = 42 10 | var got int 11 | 12 | got = IntValueWithDefault(&v, 0) 13 | if got != 42 { 14 | t.Errorf("want %d, got %d", 42, got) 15 | } 16 | 17 | got = IntValueWithDefault(nil, 42) 18 | if got != 42 { 19 | t.Errorf("want %d, got %d", 42, got) 20 | } 21 | } 22 | 23 | func TestInt8ValueWithDefault(t *testing.T) { 24 | var v int8 = 42 25 | var got int8 26 | 27 | got = Int8ValueWithDefault(&v, 0) 28 | if got != 42 { 29 | t.Errorf("want %d, got %d", 42, got) 30 | } 31 | 32 | got = Int8ValueWithDefault(nil, 42) 33 | if got != 42 { 34 | t.Errorf("want %d, got %d", 42, got) 35 | } 36 | } 37 | 38 | func TestInt16ValueWithDefault(t *testing.T) { 39 | var v int16 = 42 40 | var got int16 41 | 42 | got = Int16ValueWithDefault(&v, 0) 43 | if got != 42 { 44 | t.Errorf("want %d, got %d", 42, got) 45 | } 46 | 47 | got = Int16ValueWithDefault(nil, 42) 48 | if got != 42 { 49 | t.Errorf("want %d, got %d", 42, got) 50 | } 51 | } 52 | 53 | func TestInt32ValueWithDefault(t *testing.T) { 54 | var v int32 = 42 55 | var got int32 56 | 57 | got = Int32ValueWithDefault(&v, 0) 58 | if got != 42 { 59 | t.Errorf("want %d, got %d", 42, got) 60 | } 61 | 62 | got = Int32ValueWithDefault(nil, 42) 63 | if got != 42 { 64 | t.Errorf("want %d, got %d", 42, got) 65 | } 66 | } 67 | 68 | func TestInt64ValueWithDefault(t *testing.T) { 69 | var v int64 = 42 70 | var got int64 71 | 72 | got = Int64ValueWithDefault(&v, 0) 73 | if got != 42 { 74 | t.Errorf("want %d, got %d", 42, got) 75 | } 76 | 77 | got = Int64ValueWithDefault(nil, 42) 78 | if got != 42 { 79 | t.Errorf("want %d, got %d", 42, got) 80 | } 81 | } 82 | 83 | func TestUintValueWithDefault(t *testing.T) { 84 | var v uint = 42 85 | var got uint 86 | 87 | got = UintValueWithDefault(&v, 0) 88 | if got != 42 { 89 | t.Errorf("want %d, got %d", 42, got) 90 | } 91 | 92 | got = UintValueWithDefault(nil, 42) 93 | if got != 42 { 94 | t.Errorf("want %d, got %d", 42, got) 95 | } 96 | } 97 | 98 | func TestUint8ValueWithDefault(t *testing.T) { 99 | var v uint8 = 42 100 | var got uint8 101 | 102 | got = Uint8ValueWithDefault(&v, 0) 103 | if got != 42 { 104 | t.Errorf("want %d, got %d", 42, got) 105 | } 106 | 107 | got = Uint8ValueWithDefault(nil, 42) 108 | if got != 42 { 109 | t.Errorf("want %d, got %d", 42, got) 110 | } 111 | } 112 | 113 | func TestUint16ValueWithDefault(t *testing.T) { 114 | var v uint16 = 42 115 | var got uint16 116 | 117 | got = Uint16ValueWithDefault(&v, 0) 118 | if got != 42 { 119 | t.Errorf("want %d, got %d", 42, got) 120 | } 121 | 122 | got = Uint16ValueWithDefault(nil, 42) 123 | if got != 42 { 124 | t.Errorf("want %d, got %d", 42, got) 125 | } 126 | } 127 | 128 | func TestUint32ValueWithDefault(t *testing.T) { 129 | var v uint32 = 42 130 | var got uint32 131 | 132 | got = Uint32ValueWithDefault(&v, 0) 133 | if got != 42 { 134 | t.Errorf("want %d, got %d", 42, got) 135 | } 136 | 137 | got = Uint32ValueWithDefault(nil, 42) 138 | if got != 42 { 139 | t.Errorf("want %d, got %d", 42, got) 140 | } 141 | } 142 | 143 | func TestUint64ValueWithDefault(t *testing.T) { 144 | var v uint64 = 42 145 | var got uint64 146 | 147 | got = Uint64ValueWithDefault(&v, 0) 148 | if got != 42 { 149 | t.Errorf("want %d, got %d", 42, got) 150 | } 151 | 152 | got = Uint64ValueWithDefault(nil, 42) 153 | if got != 42 { 154 | t.Errorf("want %d, got %d", 42, got) 155 | } 156 | } 157 | 158 | func TestStringValueWithDefault(t *testing.T) { 159 | var v string = "foo" 160 | var got string 161 | 162 | got = StringValueWithDefault(&v, "") 163 | if got != "foo" { 164 | t.Errorf("want %q, got %q", "foo", got) 165 | } 166 | 167 | got = StringValueWithDefault(nil, "bar") 168 | if got != "bar" { 169 | t.Errorf("want %q, got %q", "bar", got) 170 | } 171 | } 172 | 173 | func TestFloat32ValueWithDefault(t *testing.T) { 174 | var v float32 = 42 175 | var got float32 176 | 177 | got = Float32ValueWithDefault(&v, 0.0) 178 | if got != 42.0 { 179 | t.Errorf("want %f, got %f", 42.0, got) 180 | } 181 | 182 | got = Float32ValueWithDefault(nil, 42.0) 183 | if got != 42.0 { 184 | t.Errorf("want %f, got %f", 42.0, got) 185 | } 186 | } 187 | 188 | func TestFloat64ValueWithDefault(t *testing.T) { 189 | var v float64 = 42 190 | var got float64 191 | 192 | got = Float64ValueWithDefault(&v, 0) 193 | if got != 42.0 { 194 | t.Errorf("want %f, got %f", 42.0, got) 195 | } 196 | 197 | got = Float64ValueWithDefault(nil, 42.0) 198 | if got != 42.0 { 199 | t.Errorf("want %f, got %f", 42.0, got) 200 | } 201 | } 202 | 203 | func TestByteValueWithDefault(t *testing.T) { 204 | var v byte = 42 205 | var got byte 206 | 207 | got = ByteValueWithDefault(&v, 0) 208 | if got != 42 { 209 | t.Errorf("want %d, got %d", 42, got) 210 | } 211 | 212 | got = ByteValueWithDefault(nil, 42) 213 | if got != 42 { 214 | t.Errorf("want %d, got %d", 42, got) 215 | } 216 | } 217 | 218 | func TestRuneValueWithDefault(t *testing.T) { 219 | var v rune = 42 220 | var got rune 221 | 222 | got = RuneValueWithDefault(&v, 0) 223 | if got != 42 { 224 | t.Errorf("want %d, got %d", 42, got) 225 | } 226 | 227 | got = RuneValueWithDefault(nil, 'a') 228 | if got != 'a' { 229 | t.Errorf("want %d, got %d", 'a', got) 230 | } 231 | } 232 | 233 | func TestBoolValueWithDefault(t *testing.T) { 234 | var v bool = true 235 | var got bool 236 | 237 | got = BoolValueWithDefault(&v, false) 238 | if got != true { 239 | t.Errorf("want %t, got %t", true, got) 240 | } 241 | 242 | got = BoolValueWithDefault(nil, true) 243 | if got != true { 244 | t.Errorf("want %t, got %t", true, got) 245 | } 246 | } 247 | 248 | func TestTimeValueWithDefault(t *testing.T) { 249 | v := time.Date(2020, time.January, 17, 2, 19, 0, 0, time.UTC) 250 | var got time.Time 251 | 252 | got = TimeValueWithDefault(&v, time.Time{}) 253 | if !got.Equal(v) { 254 | t.Errorf("want %s, got %s", v, got) 255 | } 256 | 257 | got = TimeValueWithDefault(nil, v) 258 | if !got.Equal(v) { 259 | t.Errorf("want %s, got %s", v, got) 260 | } 261 | } 262 | 263 | func TestComplex64ValueWithDefault(t *testing.T) { 264 | var v complex64 = complex(1, 2) 265 | var def complex64 = complex(3, 4) 266 | var got complex64 267 | 268 | got = Complex64ValueWithDefault(&v, def) 269 | if got != v { 270 | t.Errorf("want %v, got %v", v, got) 271 | } 272 | 273 | got = Complex64ValueWithDefault(nil, def) 274 | if got != def { 275 | t.Errorf("want %v, got %v", def, got) 276 | } 277 | } 278 | 279 | func TestComplex128ValueWithDefault(t *testing.T) { 280 | var v complex128 = complex(1, 2) 281 | var def complex128 = complex(3, 4) 282 | var got complex128 283 | 284 | got = Complex128ValueWithDefault(&v, def) 285 | if got != v { 286 | t.Errorf("want %v, got %v", v, got) 287 | } 288 | 289 | got = Complex128ValueWithDefault(nil, def) 290 | if got != def { 291 | t.Errorf("want %v, got %v", def, got) 292 | } 293 | } 294 | -------------------------------------------------------------------------------- /value_test.go: -------------------------------------------------------------------------------- 1 | package pointer 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func TestIntValue(t *testing.T) { 9 | var v int = 42 10 | var got int 11 | 12 | got = IntValue(&v) 13 | if got != 42 { 14 | t.Errorf("want %d, got %d", 42, got) 15 | } 16 | 17 | got = IntValue(nil) 18 | if got != 0 { 19 | t.Errorf("want %d, got %d", 0, got) 20 | } 21 | } 22 | 23 | func TestInt8Value(t *testing.T) { 24 | var v int8 = 42 25 | var got int8 26 | 27 | got = Int8Value(&v) 28 | if got != 42 { 29 | t.Errorf("want %d, got %d", 42, got) 30 | } 31 | 32 | got = Int8Value(nil) 33 | if got != 0 { 34 | t.Errorf("want %d, got %d", 0, got) 35 | } 36 | } 37 | 38 | func TestInt16Value(t *testing.T) { 39 | var v int16 = 42 40 | var got int16 41 | 42 | got = Int16Value(&v) 43 | if got != 42 { 44 | t.Errorf("want %d, got %d", 42, got) 45 | } 46 | 47 | got = Int16Value(nil) 48 | if got != 0 { 49 | t.Errorf("want %d, got %d", 0, got) 50 | } 51 | } 52 | 53 | func TestInt32Value(t *testing.T) { 54 | var v int32 = 42 55 | var got int32 56 | 57 | got = Int32Value(&v) 58 | if got != 42 { 59 | t.Errorf("want %d, got %d", 42, got) 60 | } 61 | 62 | got = Int32Value(nil) 63 | if got != 0 { 64 | t.Errorf("want %d, got %d", 0, got) 65 | } 66 | } 67 | 68 | func TestInt64Value(t *testing.T) { 69 | var v int64 = 42 70 | var got int64 71 | 72 | got = Int64Value(&v) 73 | if got != 42 { 74 | t.Errorf("want %d, got %d", 42, got) 75 | } 76 | 77 | got = Int64Value(nil) 78 | if got != 0 { 79 | t.Errorf("want %d, got %d", 0, got) 80 | } 81 | } 82 | 83 | func TestUintValue(t *testing.T) { 84 | var v uint = 42 85 | var got uint 86 | 87 | got = UintValue(&v) 88 | if got != 42 { 89 | t.Errorf("want %d, got %d", 42, got) 90 | } 91 | 92 | got = UintValue(nil) 93 | if got != 0 { 94 | t.Errorf("want %d, got %d", 0, got) 95 | } 96 | } 97 | 98 | func TestUint8Value(t *testing.T) { 99 | var v uint8 = 42 100 | var got uint8 101 | 102 | got = Uint8Value(&v) 103 | if got != 42 { 104 | t.Errorf("want %d, got %d", 42, got) 105 | } 106 | 107 | got = Uint8Value(nil) 108 | if got != 0 { 109 | t.Errorf("want %d, got %d", 0, got) 110 | } 111 | } 112 | 113 | func TestUint16Value(t *testing.T) { 114 | var v uint16 = 42 115 | var got uint16 116 | 117 | got = Uint16Value(&v) 118 | if got != 42 { 119 | t.Errorf("want %d, got %d", 42, got) 120 | } 121 | 122 | got = Uint16Value(nil) 123 | if got != 0 { 124 | t.Errorf("want %d, got %d", 0, got) 125 | } 126 | } 127 | 128 | func TestUint32Value(t *testing.T) { 129 | var v uint32 = 42 130 | var got uint32 131 | 132 | got = Uint32Value(&v) 133 | if got != 42 { 134 | t.Errorf("want %d, got %d", 42, got) 135 | } 136 | 137 | got = Uint32Value(nil) 138 | if got != 0 { 139 | t.Errorf("want %d, got %d", 0, got) 140 | } 141 | } 142 | 143 | func TestUint64Value(t *testing.T) { 144 | var v uint64 = 42 145 | var got uint64 146 | 147 | got = Uint64Value(&v) 148 | if got != 42 { 149 | t.Errorf("want %d, got %d", 42, got) 150 | } 151 | 152 | got = Uint64Value(nil) 153 | if got != 0 { 154 | t.Errorf("want %d, got %d", 0, got) 155 | } 156 | } 157 | 158 | func TestStringValue(t *testing.T) { 159 | var v string = "foo" 160 | var got string 161 | 162 | got = StringValue(&v) 163 | if got != "foo" { 164 | t.Errorf("want %q, got %q", "foo", got) 165 | } 166 | 167 | got = StringValue(nil) 168 | if got != "" { 169 | t.Errorf("want %q, got %q", "", got) 170 | } 171 | } 172 | 173 | func TestFloat32Value(t *testing.T) { 174 | var v float32 = 42 175 | var got float32 176 | 177 | got = Float32Value(&v) 178 | if got != 42.0 { 179 | t.Errorf("want %f, got %f", 42.0, got) 180 | } 181 | 182 | got = Float32Value(nil) 183 | if got != 0.0 { 184 | t.Errorf("want %f, got %f", 0.0, got) 185 | } 186 | } 187 | 188 | func TestFloat64Value(t *testing.T) { 189 | var v float64 = 42 190 | var got float64 191 | 192 | got = Float64Value(&v) 193 | if got != 42.0 { 194 | t.Errorf("want %f, got %f", 42.0, got) 195 | } 196 | 197 | got = Float64Value(nil) 198 | if got != 0.0 { 199 | t.Errorf("want %f, got %f", 0.0, got) 200 | } 201 | } 202 | 203 | func TestByteValue(t *testing.T) { 204 | var v byte = 42 205 | var got byte 206 | 207 | got = ByteValue(&v) 208 | if got != 42 { 209 | t.Errorf("want %d, got %d", 42, got) 210 | } 211 | 212 | got = ByteValue(nil) 213 | if got != 0 { 214 | t.Errorf("want %d, got %d", 0, got) 215 | } 216 | } 217 | 218 | func TestRuneValue(t *testing.T) { 219 | var v rune = 42 220 | var got rune 221 | 222 | got = RuneValue(&v) 223 | if got != 42 { 224 | t.Errorf("want %d, got %d", 42, got) 225 | } 226 | 227 | got = RuneValue(nil) 228 | if got != 0 { 229 | t.Errorf("want %d, got %d", 0, got) 230 | } 231 | } 232 | 233 | func TestBoolValue(t *testing.T) { 234 | var v bool = true 235 | var got bool 236 | 237 | got = BoolValue(&v) 238 | if got != true { 239 | t.Errorf("want %t, got %t", true, got) 240 | } 241 | 242 | got = BoolValue(nil) 243 | if got != false { 244 | t.Errorf("want %t, got %t", false, got) 245 | } 246 | } 247 | 248 | func TestTimeValue(t *testing.T) { 249 | v := time.Date(2020, time.January, 17, 2, 19, 0, 0, time.UTC) 250 | var got time.Time 251 | 252 | got = TimeValue(&v) 253 | if !got.Equal(v) { 254 | t.Errorf("want %s, got %s", v, got) 255 | } 256 | 257 | got = TimeValue(nil) 258 | if !got.IsZero() { 259 | t.Errorf("want %s, got %s", time.Time{}, got) 260 | } 261 | } 262 | 263 | func TestComplex64Value(t *testing.T) { 264 | var v complex64 = 4 + 2i 265 | var got complex64 266 | 267 | got = Complex64Value(&v) 268 | if got != 4+2i { 269 | t.Errorf("want %f, got %f", 4+2i, got) 270 | } 271 | 272 | got = Complex64Value(nil) 273 | if got != 0 { 274 | t.Errorf("want %f, got %f", 4+2i, got) 275 | } 276 | } 277 | 278 | func TestComplex128Value(t *testing.T) { 279 | var v complex128 = 4 + 2i 280 | var got complex128 281 | 282 | got = Complex128Value(&v) 283 | if got != 4+2i { 284 | t.Errorf("want %f, got %f", 4+2i, got) 285 | } 286 | 287 | got = Complex128Value(nil) 288 | if got != 0 { 289 | t.Errorf("want %f, got %f", 4+2i, got) 290 | } 291 | } 292 | --------------------------------------------------------------------------------