Skip to content

Commit 942b415

Browse files
committed
optional: implemented new generic type for optional types
* Implemented new generic option.Generic[T] type for safe and fast optional value handling. * Modified golangci-lint to ignore some irrelevant checks for tests and fixed error in exception configuration Closes #TNTP-3730
1 parent b2f62c3 commit 942b415

24 files changed

+643
-4
lines changed

.golangci.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@ linters:
2020

2121
exclusions:
2222
rules:
23-
- path-except: cmd/generator/*.go
23+
- path: cmd/generator/
2424
linters:
2525
- forbidigo # fmt functions are not forbidden here
2626
- gochecknoglobals # global variables are not forbidden here
27+
- path: _test.go
28+
linters:
29+
- wrapcheck
2730

2831
settings:
2932
godot:

bool_gen.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

byte_gen.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bytes_gen.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/generator/generator.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ type {{.Name}} struct {
239239
exists bool
240240
}
241241
242+
var _ commonInterface[{{.Type}}] = (*{{.Name}})(nil)
243+
242244
// Some{{.Name}} creates an optional {{.Name}} with the given {{.Type}} value.
243245
// The returned {{.Name}} will have IsSome() == true and IsZero() == false.
244246
//

doc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Package option provides a type-safe way to represent optional values in Go.
2-
// An Optional[T] can either contain a value of type T (Some) or be empty (None).
2+
// A Generic[T] can either contain a value of type T (Some) or be empty (None).
33
//
44
// This is useful for:
55
// - Clearly representing nullable fields in structs.

errors.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ func newDecodeWithCodeError(operationType string, code byte) error {
2828
}
2929
}
3030

31+
func getGenericTypeName[T any]() string {
32+
return fmt.Sprintf("Generic[%T]", zero[T]())
33+
}
34+
3135
func newDecodeError(operationType string, err error) error {
3236
if err == nil {
3337
return nil
@@ -40,6 +44,18 @@ func newDecodeError(operationType string, err error) error {
4044
}
4145
}
4246

47+
func newDecodeGenericError[T any](err error) error {
48+
if err == nil {
49+
return nil
50+
}
51+
52+
return DecodeError{
53+
Type: getGenericTypeName[T](),
54+
Code: NoneByte(),
55+
Parent: err,
56+
}
57+
}
58+
4359
// EncodeError is returned when encoding failed due to stream errors.
4460
type EncodeError struct {
4561
Type string
@@ -58,3 +74,11 @@ func newEncodeError(operationType string, err error) error {
5874

5975
return EncodeError{Type: operationType, Parent: err}
6076
}
77+
78+
func newEncodeGenericError[T any](err error) error {
79+
if err == nil {
80+
return nil
81+
}
82+
83+
return EncodeError{Type: getGenericTypeName[T](), Parent: err}
84+
}

errors_test.go

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
package option //nolint:testpackage
2+
23
// this is unit test, that checks internal logic of error constructing.
34

45
import (
@@ -13,7 +14,7 @@ var (
1314
errTest = errors.New("some error")
1415
)
1516

16-
func TestDecodeError_Error(t *testing.T) {
17+
func TestEncodeError_Error(t *testing.T) {
1718
t.Parallel()
1819

1920
t.Run("newEncodeError with error", func(t *testing.T) {
@@ -32,9 +33,26 @@ func TestDecodeError_Error(t *testing.T) {
3233

3334
require.NoError(t, a)
3435
})
36+
37+
t.Run("newEncoderGenericError", func(t *testing.T) {
38+
t.Parallel()
39+
40+
a := newEncodeGenericError[int](errTest)
41+
42+
require.Error(t, a)
43+
assert.Equal(t, "failed to encode Generic[int]: some error", a.Error())
44+
})
45+
46+
t.Run("newEncodeGenericError without error", func(t *testing.T) {
47+
t.Parallel()
48+
49+
a := newEncodeGenericError[int](nil)
50+
51+
require.NoError(t, a)
52+
})
3553
}
3654

37-
func TestEncodeError_Error(t *testing.T) {
55+
func TestDecodeError_Error(t *testing.T) {
3856
t.Parallel()
3957

4058
t.Run("newDecodeError with error", func(t *testing.T) {
@@ -62,4 +80,21 @@ func TestEncodeError_Error(t *testing.T) {
6280
require.Error(t, a)
6381
assert.Equal(t, "failed to decode Byte, invalid code: 1", a.Error())
6482
})
83+
84+
t.Run("newDecodeGenericError", func(t *testing.T) {
85+
t.Parallel()
86+
87+
a := newDecodeGenericError[int](errTest)
88+
89+
require.Error(t, a)
90+
assert.Equal(t, "failed to decode Generic[int]: some error", a.Error())
91+
})
92+
93+
t.Run("newDecodeGenericError without error", func(t *testing.T) {
94+
t.Parallel()
95+
96+
a := newDecodeGenericError[int](nil)
97+
98+
require.NoError(t, a)
99+
})
65100
}

float32_gen.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

float64_gen.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)