Skip to content

Commit dcdf78e

Browse files
committed
feat: add missing methods, add Rakefile
1 parent 36e5c29 commit dcdf78e

File tree

11 files changed

+993
-165
lines changed

11 files changed

+993
-165
lines changed

.github/workflows/matrix-test.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,17 @@ jobs:
2020
matrix:
2121
go:
2222
- "1.25"
23-
- "1.18"
23+
- "1.18.0"
2424

2525
steps:
2626
- uses: actions/checkout@v5
2727
- name: Set up Golang
2828
uses: actions/setup-go@v5
2929
with:
3030
go-version: ${{ matrix.go }}
31+
# - name: Install Rake
32+
# run: gem install rake
3133
- name: Test option
32-
run: cd option && go test -v
34+
run: rake test_option
3335
- name: Test result
34-
run: cd result && go test -v
36+
run: rake test_result

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/**/*.rs

README.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
# type
1+
# types
22

3-
Bring the Rust [Result Option] type to Golang
3+
Bring the Rust [Result Option] types to Golang
44

55
## Installation
66

7-
`go get github.com/initdc/type`
7+
`go get github.com/initdc/types`
88

99
## Usage
1010

1111
```go
1212
import (
13-
. "github.com/initdc/type/option"
14-
. "github.com/initdc/type/result"
13+
. "github.com/initdc/types"
1514
)
1615

1716
// Option
@@ -36,4 +35,4 @@ e := Err[int, string]("error")
3635

3736
## Contributing
3837

39-
Bug reports and pull requests are welcome on GitHub at https://github.com/initdc/type.
38+
Bug reports and pull requests are welcome on GitHub at https://github.com/initdc/types.

Rakefile

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
task default: %w[fmt vet test]
2+
3+
task :fmt do
4+
sh "go fmt ./..."
5+
end
6+
7+
task :vet do
8+
sh "go vet ./..."
9+
end
10+
11+
task :test do
12+
sh "go test -cover -v ./..."
13+
end
14+
15+
task :test_result do
16+
sh "go test -cover -v ./result"
17+
end
18+
19+
task :test_option do
20+
sh "go test -cover -v ./option"
21+
end

e2e_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package e2e_test
2+
3+
import (
4+
"fmt"
5+
. "github.com/initdc/types"
6+
"testing"
7+
)
8+
9+
func TestE2E(t *testing.T) {
10+
// Option
11+
s1 := Some(1)
12+
13+
var s2 Option[int]
14+
s2.None()
15+
16+
n1 := None[int]()
17+
18+
19+
// Result
20+
var r1 Result[int, string]
21+
r1.Ok(1)
22+
23+
var e1 Result[int, string]
24+
e1.Err("error")
25+
26+
r2 := Ok[int, string](1)
27+
e2 := Err[int, string]("error")
28+
29+
30+
fmt.Println("%v", s1)
31+
fmt.Println("%v", s2)
32+
fmt.Println("%v", n1)
33+
34+
fmt.Println("%v", r1)
35+
fmt.Println("%v", e1)
36+
fmt.Println("%v", r2)
37+
fmt.Println("%v", e2)
38+
}

go.mod

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1-
module github.com/initdc/type
1+
module github.com/initdc/types
22

3-
go 1.18
3+
go 1.18.0
4+
5+
require github.com/stretchr/testify v1.11.1
6+
7+
require (
8+
github.com/davecgh/go-spew v1.1.1 // indirect
9+
github.com/pmezard/go-difflib v1.0.0 // indirect
10+
gopkg.in/yaml.v3 v3.0.1 // indirect
11+
)

go.sum

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
2+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
4+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
5+
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
6+
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
7+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
8+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
9+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

option/option.go

Lines changed: 167 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package option
22

3+
import (
4+
"github.com/initdc/types"
5+
)
6+
37
type Option[T any] struct {
4-
value T `json:"value"`
5-
some bool `json:"some"`
6-
assigned bool `json:"assigned"`
8+
value T
9+
some bool
10+
assigned bool
711
}
812

913
func Some[T any](v T) Option[T] {
@@ -21,6 +25,7 @@ func None[T any]() Option[T] {
2125
}
2226
}
2327

28+
2429
func (o *Option[T]) Some(v T) {
2530
if o.assigned {
2631
panic("Option already assigned")
@@ -38,60 +43,210 @@ func (o *Option[T]) None() {
3843
o.assigned = true
3944
}
4045

41-
func (o *Option[T]) IsSome() bool {
46+
func (o Option[T]) Valid() bool {
4247
return o.some
4348
}
4449

45-
func (o *Option[T]) IsSomeAnd(f func(T) bool) bool {
50+
func (o Option[T]) Assigned() bool {
51+
return o.assigned
52+
}
53+
54+
func (o Option[T]) IsSome() bool {
55+
return o.some
56+
}
57+
58+
func (o Option[T]) IsSomeAnd(f func(T) bool) bool {
4659
if !o.some {
4760
return false
4861
}
4962
return f(o.value)
5063
}
5164

52-
func (o *Option[T]) IsNone() bool {
65+
func (o Option[T]) IsNone() bool {
5366
return !o.some
5467
}
5568

56-
func (o *Option[T]) IsNoneOr(f func(T) bool) bool {
69+
func (o Option[T]) IsNoneOr(f func(T) bool) bool {
5770
if !o.some {
5871
return true
5972
}
6073
return f(o.value)
6174
}
6275

63-
func (o *Option[T]) Expect(msg string) T {
76+
func (o Option[T]) Expect(msg string) T {
6477
if o.some {
6578
return o.value
6679
}
6780
panic(msg)
6881
}
6982

70-
func (o *Option[T]) Unwrap() T {
83+
func (o Option[T]) Unwrap() T {
7184
if o.some {
7285
return o.value
7386
}
7487
panic("called Option.Unwrap() on a None value")
7588
}
7689

77-
func (o *Option[T]) UnwrapOr(def T) T {
90+
func (o Option[T]) UnwrapOr(def T) T {
7891
if o.some {
7992
return o.value
8093
}
8194
return def
8295
}
8396

84-
func (o *Option[T]) UnwrapOrElse(f func() T) T {
97+
func (o Option[T]) UnwrapOrElse(f func() T) T {
8598
if o.some {
8699
return o.value
87100
}
88101
return f()
89102
}
90103

91-
func (o *Option[T]) UnwrapOrDefault() T {
104+
func (o Option[T]) UnwrapOrDefault() T {
92105
if o.some {
93106
return o.value
94107
}
95108
var zero T
96109
return zero
97110
}
111+
112+
func Map[T, U any](o Option[T], f func(T) U) Option[U] {
113+
if o.some {
114+
return Some[U](f(o.value))
115+
}
116+
return None[U]()
117+
}
118+
119+
func (o Option[T]) Inspect(f func(T)) Option[T] {
120+
if o.some {
121+
f(o.value)
122+
}
123+
return o
124+
}
125+
126+
func MapOr[T, U any](o Option[T], def U, f func(T) U) U {
127+
if o.some {
128+
return f(o.value)
129+
}
130+
return def
131+
}
132+
133+
func MapOrElse[T, U any](o Option[T], def func() U, f func(T) U) U {
134+
if o.some {
135+
return f(o.value)
136+
}
137+
return def()
138+
}
139+
140+
func MapOrDefault[T, U any](o Option[T], f func(T) U) U {
141+
if o.some {
142+
return f(o.value)
143+
}
144+
var zero U
145+
return zero
146+
}
147+
148+
func OkOr[T, E any](o Option[T], err E) result.Result[T, E] {
149+
if o.some {
150+
return result.Ok[T, E](o.value)
151+
}
152+
return result.Err[T, E](err)
153+
}
154+
155+
func OkOrElse[T, E any](o Option[T], err func() E) result.Result[T, E] {
156+
if o.some {
157+
return result.Ok[T, E](o.value)
158+
}
159+
return result.Err[T, E](err())
160+
}
161+
162+
func And[T, U any](o Option[T], optb Option[U]) Option[U] {
163+
if o.some {
164+
return optb
165+
}
166+
return None[U]()
167+
}
168+
169+
func AndThen[T, U any](o Option[T], f func(T) Option[U]) Option[U] {
170+
if o.some {
171+
return f(o.value)
172+
}
173+
return None[U]()
174+
}
175+
176+
func (o Option[T]) Filter(predicate func(T) bool) Option[T] {
177+
if o.some && predicate(o.value) {
178+
return Some[T](o.value)
179+
}
180+
return None[T]()
181+
}
182+
183+
func (o Option[T]) Or(optb Option[T]) Option[T] {
184+
if o.some {
185+
return o
186+
}
187+
return optb
188+
}
189+
190+
func (o Option[T]) OrElse(f func() Option[T]) Option[T] {
191+
if o.some {
192+
return o
193+
}
194+
return f()
195+
}
196+
197+
func (o Option[T]) Xor(optb Option[T]) Option[T] {
198+
if o.some && !optb.some {
199+
return o
200+
}
201+
if !o.some && optb.some {
202+
return optb
203+
}
204+
return None[T]()
205+
}
206+
207+
func (o *Option[T]) Insert(value T) *T {
208+
o.value = value
209+
o.some = true
210+
o.assigned = true
211+
return &o.value
212+
}
213+
214+
func (o *Option[T]) GetOrInsert(value T) *T {
215+
if !o.some {
216+
o.value = value
217+
o.some = true
218+
o.assigned = true
219+
}
220+
return &o.value
221+
}
222+
223+
func (o *Option[T]) GetOrInsertDefault() *T {
224+
if !o.some {
225+
var zero T
226+
o.value = zero
227+
o.some = true
228+
o.assigned = true
229+
}
230+
return &o.value
231+
}
232+
233+
func (o *Option[T]) GetOrInsertWith(f func() T) *T {
234+
if !o.some {
235+
o.value = f()
236+
o.some = true
237+
o.assigned = true
238+
}
239+
return &o.value
240+
}
241+
242+
func (o *Option[T]) Take() Option[T] {
243+
var cp = *o
244+
*o = None[T]()
245+
return cp
246+
}
247+
248+
func (o *Option[T]) Replace(value T) Option[T] {
249+
var cp = *o
250+
*o = Some[T](value)
251+
return cp
252+
}

0 commit comments

Comments
 (0)