Skip to content

Commit 57f770f

Browse files
committed
Remove package result, add group
1 parent 01e6fb5 commit 57f770f

21 files changed

+548
-409
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
- name: 🧸 golangci-lint
2727
uses: golangci/golangci-lint-action@v4
2828
with:
29-
version: v1.56.2
29+
version: v1.57.1
3030
- name: 🔨 Test
3131
run: go test -race ./...
3232
env:

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
!/.github/
77
!/.gitignore
88
!/.golangci.yaml
9-
!/.markdownlint.json
9+
!/.markdownlint.yaml
1010
!/.mockery.yaml
11+
!/.prettierrc.yaml
1112
!/.yamlfmt
1213
!/.yamllint
1314
/bin/

.markdownlint.json

Lines changed: 0 additions & 11 deletions
This file was deleted.

.markdownlint.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
no-hard-tabs:
3+
ignore_code_languages:
4+
- go
5+
spaces_per_tab: 4
6+
line-length:
7+
line_length: 120

.prettierrc.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
printWidth: 120
3+
proseWrap: always
4+
tabWidth: 4
5+
useTabs: false
6+
overrides:
7+
- files: "*.md"
8+
options:
9+
tabWidth: 2

README.md

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
[![Maintainability](https://api.codeclimate.com/v1/badges/12a77c18122e2d1e1f6b/maintainability)](https://codeclimate.com/github/fillmore-labs/promise/maintainability)
88
[![Go Report Card](https://goreportcard.com/badge/fillmore-labs.com/promise)](https://goreportcard.com/report/fillmore-labs.com/promise)
99
[![License](https://img.shields.io/github/license/fillmore-labs/promise)](https://www.apache.org/licenses/LICENSE-2.0)
10-
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Ffillmore-labs%2Fpromise.svg?type=shield&issueType=license)](https://app.fossa.com/projects/git%2Bgithub.com%2Ffillmore-labs%2Fpromise?ref=badge_shield&issueType=license)
10+
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Ffillmore-labs%2Fpromise.svg?type=shield&issueType=license)](https://app.fossa.com/projects/git%2Bgithub.com%2Ffillmore-labs%2Fpromise)
1111

1212
The `promise` package provides interfaces and utilities for writing asynchronous code in Go.
1313

@@ -16,19 +16,18 @@ The `promise` package provides interfaces and utilities for writing asynchronous
1616
Promises and futures are constructs used for asynchronous and concurrent programming, allowing developers to work with
1717
values that may not be immediately available and can be evaluated in a different execution context.
1818

19-
Go is known for its built-in concurrency features like goroutines and channels.
20-
The select statement further allows for efficient multiplexing and synchronization of multiple channels, thereby
21-
enabling developers to coordinate and orchestrate asynchronous operations effectively.
22-
Additionally, the context package offers a standardized way to manage cancellation, deadlines, and timeouts within
23-
concurrent and asynchronous code.
19+
Go is known for its built-in concurrency features like goroutines and channels. The select statement further allows for
20+
efficient multiplexing and synchronization of multiple channels, thereby enabling developers to coordinate and
21+
orchestrate asynchronous operations effectively. Additionally, the context package offers a standardized way to manage
22+
cancellation, deadlines, and timeouts within concurrent and asynchronous code.
2423

2524
On the other hand, Go's error handling mechanism, based on explicit error values returned from functions, provides a
2625
clear and concise way to handle errors.
2726

28-
The purpose of this package is to provide a library which simplifies the integration of concurrent
29-
code while providing a cohesive strategy for handling asynchronous errors.
30-
By adhering to Go's standard conventions for asynchronous and concurrent code, as well as error propagation, this
31-
package aims to enhance developer productivity and code reliability in scenarios requiring asynchronous operations.
27+
The purpose of this package is to provide a library which simplifies the integration of concurrent code while providing
28+
a cohesive strategy for handling asynchronous errors. By adhering to Go's standard conventions for asynchronous and
29+
concurrent code, as well as error propagation, this package aims to enhance developer productivity and code reliability
30+
in scenarios requiring asynchronous operations.
3231

3332
## Usage
3433

combine.go

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ import (
2020
"context"
2121
"fmt"
2222
"reflect"
23-
24-
"fillmore-labs.com/promise/result"
2523
)
2624

2725
// AnyFuture matches a [Future] of any type.
@@ -31,36 +29,32 @@ type AnyFuture interface {
3129

3230
// AwaitAll returns a function that yields the results of all futures.
3331
// If the context is canceled, it returns an error for the remaining futures.
34-
func AwaitAll[R any](ctx context.Context, futures ...Future[R]) func(yield func(int, result.Result[R]) bool) {
35-
i := newIterator(ctx, convertValue[R], futures)
36-
37-
return i.yieldTo
32+
func AwaitAll[R any](ctx context.Context, futures ...Future[R]) func(yield func(int, Result[R]) bool) {
33+
return newIterator(ctx, convertValue[R], futures)
3834
}
3935

4036
// AwaitAllAny returns a function that yields the results of all futures.
4137
// If the context is canceled, it returns an error for the remaining futures.
42-
func AwaitAllAny(ctx context.Context, futures ...AnyFuture) func(yield func(int, result.Result[any]) bool) {
43-
i := newIterator(ctx, convertValueAny, futures)
44-
45-
return i.yieldTo
38+
func AwaitAllAny(ctx context.Context, futures ...AnyFuture) func(yield func(int, Result[any]) bool) {
39+
return newIterator(ctx, convertValueAny, futures)
4640
}
4741

4842
// AwaitAllResults waits for all futures to complete and returns the results.
4943
// If the context is canceled, it returns early with errors for the remaining futures.
50-
func AwaitAllResults[R any](ctx context.Context, futures ...Future[R]) []result.Result[R] {
44+
func AwaitAllResults[R any](ctx context.Context, futures ...Future[R]) []Result[R] {
5145
return awaitAllResults(len(futures), AwaitAll(ctx, futures...))
5246
}
5347

5448
// AwaitAllResultsAny waits for all futures to complete and returns the results.
5549
// If the context is canceled, it returns early with errors for the remaining futures.
56-
func AwaitAllResultsAny(ctx context.Context, futures ...AnyFuture) []result.Result[any] {
50+
func AwaitAllResultsAny(ctx context.Context, futures ...AnyFuture) []Result[any] {
5751
return awaitAllResults(len(futures), AwaitAllAny(ctx, futures...))
5852
}
5953

60-
func awaitAllResults[R any](n int, iter func(yield func(int, result.Result[R]) bool)) []result.Result[R] {
61-
results := make([]result.Result[R], n)
54+
func awaitAllResults[R any](n int, iter func(yield func(int, Result[R]) bool)) []Result[R] {
55+
results := make([]Result[R], n)
6256

63-
iter(func(i int, r result.Result[R]) bool {
57+
iter(func(i int, r Result[R]) bool {
6458
results[i] = r
6559

6660
return true
@@ -81,17 +75,17 @@ func AwaitAllValuesAny(ctx context.Context, futures ...AnyFuture) ([]any, error)
8175
return awaitAllValues(len(futures), AwaitAllAny(ctx, futures...))
8276
}
8377

84-
func awaitAllValues[R any](n int, iter func(yield func(int, result.Result[R]) bool)) ([]R, error) {
78+
func awaitAllValues[R any](n int, iter func(yield func(int, Result[R]) bool)) ([]R, error) {
8579
results := make([]R, n)
8680
var yieldErr error
8781

88-
iter(func(i int, r result.Result[R]) bool {
89-
if r.Err() != nil {
90-
yieldErr = fmt.Errorf("list AwaitAllValues result %d: %w", i, r.Err())
82+
iter(func(i int, r Result[R]) bool {
83+
if r.Err != nil {
84+
yieldErr = fmt.Errorf("list AwaitAllValues result %d: %w", i, r.Err)
9185

9286
return false
9387
}
94-
results[i] = r.Value()
88+
results[i] = r.Value
9589

9690
return true
9791
})
@@ -111,11 +105,11 @@ func AwaitFirstAny(ctx context.Context, futures ...AnyFuture) (any, error) {
111105
return awaitFirst(AwaitAllAny(ctx, futures...))
112106
}
113107

114-
func awaitFirst[R any](iter func(yield func(int, result.Result[R]) bool)) (R, error) {
115-
var v result.Result[R]
108+
func awaitFirst[R any](iter func(yield func(int, Result[R]) bool)) (R, error) {
109+
var v *Result[R]
116110

117-
iter(func(_ int, r result.Result[R]) bool {
118-
v = r
111+
iter(func(_ int, r Result[R]) bool {
112+
v = &r
119113

120114
return false
121115
})
@@ -124,5 +118,5 @@ func awaitFirst[R any](iter func(yield func(int, result.Result[R]) bool)) (R, er
124118
return *new(R), ErrNoResult
125119
}
126120

127-
return v.V()
121+
return v.Value, v.Err
128122
}

combine_all_test.go

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"testing"
2424

2525
"fillmore-labs.com/promise"
26-
"fillmore-labs.com/promise/result"
2726
"github.com/stretchr/testify/assert"
2827
)
2928

@@ -49,20 +48,18 @@ func TestAll(t *testing.T) {
4948
defer cancel()
5049

5150
// when
52-
results := make([]result.Result[int], len(futures))
51+
results := make([]promise.Result[int], len(futures))
5352
for i, r := range promise.AwaitAll(ctx, futures...) { //nolint:typecheck
5453
results[i] = r
5554
}
5655

5756
// then
58-
if assert.NoError(t, results[0].Err()) {
59-
assert.Equal(t, 1, results[0].Value())
57+
if assert.NoError(t, results[0].Err) {
58+
assert.Equal(t, 1, results[0].Value)
6059
}
61-
if assert.ErrorIs(t, results[1].Err(), errTest) {
62-
_ = results[1].Value() // Should not panic
63-
}
64-
if assert.NoError(t, results[2].Err()) {
65-
assert.Equal(t, 2, results[2].Value())
60+
assert.ErrorIs(t, results[1].Err, errTest)
61+
if assert.NoError(t, results[2].Err) {
62+
assert.Equal(t, 2, results[2].Value)
6663
}
6764
}
6865

@@ -99,21 +96,21 @@ func TestAnyAll(t *testing.T) {
9996
p3.Resolve(struct{}{})
10097

10198
// when
102-
results := make([]result.Result[any], 3)
99+
results := make([]promise.Result[any], 3)
103100
for i, r := range promise.AwaitAllAny(ctx, f1, f2, f3) { //nolint:typecheck
104101
results[i] = r
105102
}
106103

107104
// then
108105
for i, r := range results {
109-
if assert.NoError(t, r.Err()) {
106+
if assert.NoError(t, r.Err) {
110107
switch i {
111108
case 0:
112-
assert.Equal(t, 1, r.Value())
109+
assert.Equal(t, 1, r.Value)
113110
case 1:
114-
assert.Equal(t, "test", r.Value())
111+
assert.Equal(t, "test", r.Value)
115112
case 2:
116-
assert.Equal(t, struct{}{}, r.Value())
113+
assert.Equal(t, struct{}{}, r.Value)
117114
default:
118115
assert.Fail(t, "unexpected index")
119116
}

combine_test.go

Lines changed: 21 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"testing"
2222

2323
"fillmore-labs.com/promise"
24-
"fillmore-labs.com/promise/result"
2524
"github.com/stretchr/testify/assert"
2625
)
2726

@@ -54,9 +53,9 @@ func TestWaitAll(t *testing.T) {
5453

5554
// then
5655
assert.Len(t, results, len(futures))
57-
v0, err0 := results[0].V()
58-
_, err1 := results[1].V()
59-
_, err2 := results[2].V()
56+
v0, err0 := results[0].Value, results[0].Err
57+
err1 := results[1].Err
58+
err2 := results[2].Err
6059

6160
if assert.NoError(t, err0) {
6261
assert.Equal(t, 1, v0)
@@ -134,7 +133,7 @@ func TestCombineCancellation(t *testing.T) {
134133
{name: "All", combine: func(futures []promise.Future[int], ctx context.Context) error {
135134
r := promise.AwaitAllResults(ctx, futures...)
136135

137-
return r[0].Err()
136+
return r[0].Err
138137
}},
139138
{name: "AllValues", combine: func(futures []promise.Future[int], ctx context.Context) error {
140139
_, err := promise.AwaitAllValues(ctx, futures...)
@@ -181,15 +180,15 @@ func TestCombineMemoized(t *testing.T) {
181180
return promise.AwaitAllResults(ctx, futures...), nil
182181
}, expect: func(t *testing.T, actual any) {
183182
t.Helper()
184-
vv, ok := actual.([]result.Result[int])
183+
vv, ok := actual.([]promise.Result[int])
185184
if !ok {
186185
assert.Fail(t, "Unexpected result type")
187186

188187
return
189188
}
190189

191190
for _, v := range vv {
192-
value, err := v.V()
191+
value, err := v.Value, v.Err
193192
if assert.NoError(t, err) {
194193
assert.Equal(t, 3, value)
195194
}
@@ -282,55 +281,32 @@ func TestAllAny(t *testing.T) {
282281
p3, f3 := promise.New[struct{}]()
283282

284283
p1.Resolve(1)
285-
p2.Resolve("test")
284+
close(p2)
286285
p3.Resolve(struct{}{})
287286

288287
// when
289-
results := make([]result.Result[any], 3)
290-
promise.AwaitAllAny(ctx, f1, f2, f3)(func(i int, r result.Result[any]) bool {
288+
results := make([]promise.Result[any], 3)
289+
promise.AwaitAllAny(ctx, f1, f2, f3)(func(i int, r promise.Result[any]) bool {
291290
results[i] = r
292291

293292
return true
294293
})
295294

296295
// then
297296
for i, r := range results {
298-
if assert.NoError(t, r.Err()) {
299-
switch i {
300-
case 0:
301-
assert.Equal(t, 1, r.Value())
302-
case 1:
303-
assert.Equal(t, "test", r.Value())
304-
case 2:
305-
assert.Equal(t, struct{}{}, r.Value())
306-
default:
307-
assert.Fail(t, "unexpected index")
297+
switch i {
298+
case 0:
299+
if assert.NoError(t, r.Err) {
300+
assert.Equal(t, 1, r.Value)
308301
}
302+
case 1:
303+
assert.ErrorIs(t, r.Err, promise.ErrNoResult)
304+
case 2:
305+
if assert.NoError(t, r.Err) {
306+
assert.Equal(t, struct{}{}, r.Value)
307+
}
308+
default:
309+
assert.Fail(t, "unexpected index")
309310
}
310311
}
311312
}
312-
313-
func TestAllNil(t *testing.T) {
314-
// given
315-
t.Parallel()
316-
ctx := context.Background()
317-
318-
p1, f1 := promise.New[struct{}]()
319-
p1 <- nil
320-
321-
// when
322-
var v result.Result[any]
323-
var set bool
324-
promise.AwaitAllAny(ctx, f1)(func(_ int, r result.Result[any]) bool {
325-
if set {
326-
assert.Fail(t, "Value already set")
327-
}
328-
v = r
329-
set = true
330-
331-
return false
332-
})
333-
334-
// then
335-
assert.ErrorIs(t, v.Err(), promise.ErrNoResult)
336-
}

0 commit comments

Comments
 (0)