Skip to content

Commit

Permalink
add IO generator supporting error propagation
Browse files Browse the repository at this point in the history
  • Loading branch information
0x5a17ed committed May 15, 2024
1 parent f28948f commit 7616592
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 0 deletions.
55 changes: 55 additions & 0 deletions iters/ioit/ioit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) 2023 individual contributors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// <https://www.apache.org/licenses/LICENSE-2.0>
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ioit

import (
"sync/atomic"

"github.com/0x5a17ed/itkit/iters/genit"
)

type GeneratorFn[T any] func(yield func(T)) error

type Generator[T any] struct {
*genit.Generator[T]

err atomic.Pointer[error]
}

// Close stops the generator and returns any error returned by
// the [GeneratorFn] function.
func (g *Generator[T]) Close() error {
g.Generator.Stop()
return g.Err()
}

// Err returns any error returned by the [GeneratorFn] function.
func (g *Generator[T]) Err() error {
if err := g.err.Load(); err != nil {
return *err
}
return nil
}

func Run[T any](fn GeneratorFn[T]) *Generator[T] {
iog := &Generator[T]{}

iog.Generator = genit.Run(func(yield func(T)) {
err := fn(yield)
iog.err.Store(&err)
})

return iog
}
40 changes: 40 additions & 0 deletions iters/ioit/ioit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) 2023 individual contributors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// <https://www.apache.org/licenses/LICENSE-2.0>
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ioit_test

import (
"io/fs"
"testing"

"github.com/0x5a17ed/itkit/iters/ioit"
"github.com/stretchr/testify/assert"
"go.uber.org/goleak"
)

func TestGenerator_Err(t *testing.T) {
defer goleak.VerifyNone(t)

asserter := assert.New(t)

g := ioit.Run(func(func(any)) error {
return fs.ErrNotExist
})

asserter.NoError(g.Err())

asserter.False(g.Next())

asserter.ErrorIs(g.Err(), fs.ErrNotExist)
}

0 comments on commit 7616592

Please sign in to comment.