Skip to content

Commit

Permalink
Allow return of errors from Value func
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewSisley authored Nov 23, 2022
2 parents b56a7f8 + 2af5483 commit c1c418f
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 16 deletions.
2 changes: 1 addition & 1 deletion enumerable/concat.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (s *enumerableConcat[T]) Next() (bool, error) {
}
}

func (s *enumerableConcat[T]) Value() T {
func (s *enumerableConcat[T]) Value() (T, error) {
return s.sources[s.currentSourceIndex].Value()
}

Expand Down
19 changes: 14 additions & 5 deletions enumerable/enumerable.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Enumerable[T any] interface {
//
// If the previous Next call did not return true, or Next has never been called
// the behaviour and return value of this function is undefined.
Value() T
Value() (T, error)

// Reset resets the enumerable, allowing for re-iteration.
Reset()
Expand Down Expand Up @@ -49,8 +49,8 @@ func (s *enumerableSlice[T]) Next() (bool, error) {
return true, nil
}

func (s *enumerableSlice[T]) Value() T {
return s.source[s.currentIndex]
func (s *enumerableSlice[T]) Value() (T, error) {
return s.source[s.currentIndex], nil
}

func (s *enumerableSlice[T]) Reset() {
Expand All @@ -68,7 +68,10 @@ func ForEach[T any](source Enumerable[T], action func(item T)) error {
if !hasNext {
break
}
item := source.Value()
item, err := source.Value()
if err != nil {
return err
}
action(item)
}
source.Reset()
Expand Down Expand Up @@ -101,5 +104,11 @@ func TryGetFirst[T any](source Enumerable[T]) (T, bool, error) {
var defaultV T
return defaultV, false, err
}
return source.Value(), true, nil

val, err := source.Value()
if err != nil {
var defaultV T
return defaultV, false, err
}
return val, true, nil
}
10 changes: 7 additions & 3 deletions enumerable/select.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ func (s *enumerableSelect[TSource, TResult]) Next() (bool, error) {
return hasNext, err
}

value := s.source.Value()
value, err := s.source.Value()
if err != nil {
return false, nil
}

// We do this here to keep the work (and errors) in the `Next` call
result, err := s.selector(value)
if err != nil {
Expand All @@ -36,8 +40,8 @@ func (s *enumerableSelect[TSource, TResult]) Next() (bool, error) {
return true, nil
}

func (s *enumerableSelect[TSource, TResult]) Value() TResult {
return s.currentValue
func (s *enumerableSelect[TSource, TResult]) Value() (TResult, error) {
return s.currentValue, nil
}

func (s *enumerableSelect[TSource, TResult]) Reset() {
Expand Down
2 changes: 1 addition & 1 deletion enumerable/skip.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func (s *enumerableSkip[T]) Next() (bool, error) {
return s.source.Next()
}

func (s *enumerableSkip[T]) Value() T {
func (s *enumerableSkip[T]) Value() (T, error) {
return s.source.Value()
}

Expand Down
15 changes: 12 additions & 3 deletions enumerable/sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,14 @@ func Sort[T any](source Enumerable[T], less func(T, T) bool, capacity int) Enume
func (s *enumerableSort[T]) Next() (bool, error) {
if s.result == nil {
result := make([]T, 0, s.capacity)
var searchErr error

// Declaring an anonymous function costs, so we do it here outside of the loop
// even though it is slightly less intuitive
f := func(i int) bool {
return !s.less(result[i], s.source.Value())
var val T
val, searchErr = s.source.Value()
return !s.less(result[i], val)
}

for i := 0; i <= s.capacity; i++ {
Expand All @@ -44,7 +48,12 @@ func (s *enumerableSort[T]) Next() (bool, error) {

previousLength := len(result)
indexOfFirstGreaterValue := sort.Search(previousLength, f)
value := s.source.Value()
if searchErr != nil {
// This is quite ugly, but sort.Search does not allow for anything else
return false, searchErr
}

value, err := s.source.Value()
result = append(result, value)
if indexOfFirstGreaterValue == previousLength {
// Value is the greatest, and belongs at the end
Expand All @@ -63,7 +72,7 @@ func (s *enumerableSort[T]) Next() (bool, error) {
return s.result.Next()
}

func (s *enumerableSort[T]) Value() T {
func (s *enumerableSort[T]) Value() (T, error) {
return s.result.Value()
}

Expand Down
2 changes: 1 addition & 1 deletion enumerable/take.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (s *enumerableTake[T]) Next() (bool, error) {
return s.source.Next()
}

func (s *enumerableTake[T]) Value() T {
func (s *enumerableTake[T]) Value() (T, error) {
return s.source.Value()
}

Expand Down
8 changes: 6 additions & 2 deletions enumerable/where.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,18 @@ func (s *enumerableWhere[T]) Next() (bool, error) {
return hasNext, err
}

value := s.source.Value()
value, err := s.source.Value()
if err != nil {
return false, err
}

if passes, err := s.predicate(value); passes || err != nil {
return passes, err
}
}
}

func (s *enumerableWhere[T]) Value() T {
func (s *enumerableWhere[T]) Value() (T, error) {
return s.source.Value()
}

Expand Down

0 comments on commit c1c418f

Please sign in to comment.