iter

package
v1.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 26, 2025 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package iter provides a complete implementation of Rust's Iterator trait in Go. This package translates the Rust Iterator trait and its methods to Go, maintaining semantic equivalence while adapting to Go's type system and idioms.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Cmp added in v1.7.0

func Cmp[T gust.Ord](a Iterator[T], b Iterator[T]) gust.Ordering

Cmp lexicographically compares the elements of this Iterator with those of another.

Examples

assert.Equal(t, gust.Less(), Cmp(FromSlice([]int{1}), FromSlice([]int{1})))
assert.Equal(t, gust.Less(), Cmp(FromSlice([]int{1}), FromSlice([]int{1, 2})))
assert.Equal(t, gust.Greater(), Cmp(FromSlice([]int{1, 2}), FromSlice([]int{1})))

func CmpBy added in v1.7.0

func CmpBy[T any, U any](a Iterator[T], b Iterator[U], cmp func(T, U) int) gust.Ordering

CmpBy lexicographically compares the elements of this Iterator with those of another with respect to the specified comparison function.

Examples

var xs = []int{1, 2, 3, 4}
var ys = []int{1, 4, 9, 16}
var result = CmpBy(FromSlice(xs), FromSlice(ys), func(x, y int) int {
	if x*x < y {
		return -1
	}
	if x*x > y {
		return 1
	}
	return 0
})
assert.Equal(t, gust.Equal(), result)

func DefaultSizeHint added in v1.7.0

func DefaultSizeHint[T any]() (uint, gust.Option[uint])

DefaultSizeHint provides a default implementation of SizeHint that returns (0, None). This can be used by iterator implementations that don't have size information.

func Eq added in v1.7.0

func Eq[T comparable](a Iterator[T], b Iterator[T]) bool

Eq determines if the elements of this Iterator are equal to those of another.

Examples

assert.True(t, Eq(FromSlice([]int{1}), FromSlice([]int{1})))
assert.False(t, Eq(FromSlice([]int{1}), FromSlice([]int{1, 2})))

func EqBy added in v1.7.0

func EqBy[T any, U any](a Iterator[T], b Iterator[U], eq func(T, U) bool) bool

EqBy determines if the elements of this Iterator are equal to those of another with respect to the specified equality function.

Examples

var xs = []int{1, 2, 3, 4}
var ys = []int{1, 4, 9, 16}
assert.True(t, EqBy(FromSlice(xs), FromSlice(ys), func(x, y int) bool { return x*x == y }))

func FindMap

func FindMap[T any, U any](iter Iterator[T], f func(T) gust.Option[U]) gust.Option[U]

FindMap applies function to the elements of iterator and returns the first non-none result.

FindMap(f) is equivalent to FilterMap(iter, f).Next().

Examples

var a = []string{"lol", "NaN", "2", "5"}
var firstNumber = FindMap(FromSlice(a), func(s string) gust.Option[int] {
	if v, err := strconv.Atoi(s); err == nil {
		return gust.Some(v)
	}
	return gust.None[int]()
})
assert.Equal(t, gust.Some(2), firstNumber)

func Fold

func Fold[T any, B any](iter Iterator[T], init B, f func(B, T) B) B

Fold folds every element into an accumulator by applying an operation, returning the final result.

Fold() takes two arguments: an initial value, and a closure with two arguments: an 'accumulator', and an element. The closure returns the value that the accumulator should have for the next iteration.

The initial value is the value the accumulator will have on the first call.

After applying this closure to every element of the iterator, Fold() returns the accumulator.

This operation is sometimes called 'reduce' or 'inject'.

Folding is useful whenever you have a collection of something, and want to produce a single value from it.

Note: Fold(), and similar methods that traverse the entire iterator, might not terminate for infinite iterators, even on traits for which a result is determinable in finite time.

Note: Reduce() can be used to use the first element as the initial value, if the accumulator type and item type is the same.

Note: Fold() combines elements in a *left-associative* fashion. For associative operators like +, the order the elements are combined in is not important, but for non-associative operators like - the order will affect the final result.

Examples

Basic usage:

var a = []int{1, 2, 3}
// the sum of all of the elements of the array
var sum = Fold(FromSlice(a), 0, func(acc int, x int) int { return acc + x })
assert.Equal(t, 6, sum)

Let's walk through each step of the iteration here:

| element | acc | x | result | |---------|-----|---|--------| | | 0 | | | | 1 | 0 | 1 | 1 | | 2 | 1 | 2 | 3 | | 3 | 3 | 3 | 6 |

And so, our final result, 6.

func Ge added in v1.7.0

func Ge[T gust.Digit](a Iterator[T], b Iterator[T]) bool

Ge determines if the elements of this Iterator are lexicographically greater than or equal to those of another.

Examples

assert.True(t, Ge(FromSlice([]int{1}), FromSlice([]int{1})))
assert.False(t, Ge(FromSlice([]int{1}), FromSlice([]int{1, 2})))
assert.True(t, Ge(FromSlice([]int{1, 2}), FromSlice([]int{1})))

func Gt added in v1.7.0

func Gt[T gust.Digit](a Iterator[T], b Iterator[T]) bool

Gt determines if the elements of this Iterator are lexicographically greater than those of another.

Examples

assert.False(t, Gt(FromSlice([]int{1}), FromSlice([]int{1})))
assert.False(t, Gt(FromSlice([]int{1}), FromSlice([]int{1, 2})))
assert.True(t, Gt(FromSlice([]int{1, 2}), FromSlice([]int{1})))

func IsSorted added in v1.7.0

func IsSorted[T gust.Digit](iter Iterator[T]) bool

IsSorted checks if the elements of this iterator are sorted.

That is, for each element a and its following element b, a <= b must hold. If the iterator yields exactly zero or one element, true is returned.

Note that if T is only PartialOrd, but not Ord, the above definition implies that this function returns false if any two consecutive items are not comparable.

Examples

assert.True(t, IsSorted(FromSlice([]int{1, 2, 2, 9})))
assert.False(t, IsSorted(FromSlice([]int{1, 3, 2, 4})))
assert.True(t, IsSorted(FromSlice([]int{0})))
assert.True(t, IsSorted(Empty[int]()))

func IsSortedBy added in v1.7.0

func IsSortedBy[T any](iter Iterator[T], compare func(T, T) bool) bool

IsSortedBy checks if the elements of this iterator are sorted using the given comparator function.

Instead of using PartialOrd::partial_cmp, this function uses the given compare function to determine whether two elements are to be considered in sorted order.

Examples

assert.True(t, IsSortedBy(FromSlice([]int{1, 2, 2, 9}), func(a, b int) bool { return a <= b }))
assert.False(t, IsSortedBy(FromSlice([]int{1, 2, 2, 9}), func(a, b int) bool { return a < b }))

func IsSortedByKey added in v1.7.0

func IsSortedByKey[T any, K gust.Digit](iter Iterator[T], f func(T) K) bool

IsSortedByKey checks if the elements of this iterator are sorted using the given key extraction function.

Instead of comparing the iterator's elements directly, this function compares the keys of the elements, as determined by f. Apart from that, it's equivalent to IsSorted; see its documentation for more information.

Examples

assert.True(t, IsSortedByKey(FromSlice([]string{"c", "bb", "aaa"}), func(s string) int { return len(s) }))
assert.False(t, IsSortedByKey(FromSlice([]int{-2, -1, 0, 3}), func(n int) int {
	if n < 0 {
		return -n
	}
	return n
}))

func Le added in v1.7.0

func Le[T gust.Digit](a Iterator[T], b Iterator[T]) bool

Le determines if the elements of this Iterator are lexicographically less or equal to those of another.

Examples

assert.True(t, Le(FromSlice([]int{1}), FromSlice([]int{1})))
assert.True(t, Le(FromSlice([]int{1}), FromSlice([]int{1, 2})))
assert.False(t, Le(FromSlice([]int{1, 2}), FromSlice([]int{1})))

func Lt added in v1.7.0

func Lt[T gust.Digit](a Iterator[T], b Iterator[T]) bool

Lt determines if the elements of this Iterator are lexicographically less than those of another.

Examples

assert.False(t, Lt(FromSlice([]int{1}), FromSlice([]int{1})))
assert.True(t, Lt(FromSlice([]int{1}), FromSlice([]int{1, 2})))
assert.False(t, Lt(FromSlice([]int{1, 2}), FromSlice([]int{1})))

func Max added in v1.7.0

func Max[T gust.Ord](iter Iterator[T]) gust.Option[T]

Max returns the maximum element of an iterator.

If several elements are equally maximum, the last element is returned. If the iterator is empty, gust.None[T]() is returned.

Note that f32/f64 doesn't implement Ord due to NaN being incomparable. You can work around this by using Reduce:

var max = Reduce(FromSlice([]float32{2.4, float32(math.NaN()), 1.3}), func(a, b float32) float32 {
	if a > b {
		return a
	}
	return b
})

Examples

var a = []int{1, 2, 3}
var b = []int{}
assert.Equal(t, gust.Some(3), Max(FromSlice(a)))
assert.Equal(t, gust.None[int](), Max(FromSlice(b)))

func MaxByKey added in v1.7.0

func MaxByKey[T any, K gust.Ord](iter Iterator[T], f func(T) K) gust.Option[T]

MaxByKey returns the element that gives the maximum value from the specified function.

If several elements are equally maximum, the last element is returned. If the iterator is empty, gust.None[T]() is returned.

Examples

var a = []int{-3, 0, 1, 5, -10}
var max = MaxByKey(FromSlice(a), func(x int) int {
	if x < 0 {
		return -x
	}
	return x
})
assert.Equal(t, gust.Some(-10), max)

func Min added in v1.7.0

func Min[T gust.Ord](iter Iterator[T]) gust.Option[T]

Min returns the minimum element of an iterator.

If several elements are equally minimum, the first element is returned. If the iterator is empty, gust.None[T]() is returned.

Note that f32/f64 doesn't implement Ord due to NaN being incomparable. You can work around this by using Reduce:

var min = Reduce(FromSlice([]float32{2.4, float32(math.NaN()), 1.3}), func(a, b float32) float32 {
	if a < b {
		return a
	}
	return b
})

Examples

var a = []int{1, 2, 3}
var b = []int{}
assert.Equal(t, gust.Some(1), Min(FromSlice(a)))
assert.Equal(t, gust.None[int](), Min(FromSlice(b)))

func MinByKey added in v1.7.0

func MinByKey[T any, K gust.Ord](iter Iterator[T], f func(T) K) gust.Option[T]

MinByKey returns the element that gives the minimum value from the specified function.

If several elements are equally minimum, the first element is returned. If the iterator is empty, gust.None[T]() is returned.

Examples

var a = []int{-3, 0, 1, 5, -10}
var min = MinByKey(FromSlice(a), func(x int) int {
	if x < 0 {
		return -x
	}
	return x
})
assert.Equal(t, gust.Some(0), min)

func Ne added in v1.7.0

func Ne[T comparable](a Iterator[T], b Iterator[T]) bool

Ne determines if the elements of this Iterator are not equal to those of another.

Examples

assert.False(t, Ne(FromSlice([]int{1}), FromSlice([]int{1})))
assert.True(t, Ne(FromSlice([]int{1}), FromSlice([]int{1, 2})))

func PartialCmp added in v1.7.0

func PartialCmp[T gust.Digit](a Iterator[T], b Iterator[T]) gust.Option[gust.Ordering]

PartialCmp lexicographically compares the PartialOrd elements of this Iterator with those of another. The comparison works like short-circuit evaluation, returning a result without comparing the remaining elements. As soon as an order can be determined, the evaluation stops and a result is returned.

Examples

var result = PartialCmp(FromSlice([]float64{1.0}), FromSlice([]float64{1.0}))
assert.Equal(t, gust.Some(gust.Equal()), result)

var result2 = PartialCmp(FromSlice([]float64{1.0}), FromSlice([]float64{1.0, 2.0}))
assert.Equal(t, gust.Some(gust.Less()), result2)

// For floating-point numbers, NaN does not have a total order
var nan = []float64{0.0 / 0.0}
var result3 = PartialCmp(FromSlice(nan), FromSlice([]float64{1.0}))
assert.Equal(t, gust.None[gust.Ordering](), result3)

func PartialCmpBy added in v1.7.0

func PartialCmpBy[T any, U any](a Iterator[T], b Iterator[U], partialCmp func(T, U) gust.Option[gust.Ordering]) gust.Option[gust.Ordering]

PartialCmpBy lexicographically compares the elements of this Iterator with those of another with respect to the specified comparison function.

Examples

var xs = []float64{1.0, 2.0, 3.0, 4.0}
var ys = []float64{1.0, 4.0, 9.0, 16.0}
var result = PartialCmpBy(FromSlice(xs), FromSlice(ys), func(x, y float64) gust.Option[gust.Ordering] {
	if x*x < y {
		return gust.Some(gust.Less())
	}
	if x*x > y {
		return gust.Some(gust.Greater())
	}
	return gust.Some(gust.Equal())
})
assert.Equal(t, gust.Some(gust.Equal()), result)

func Product added in v1.7.0

func Product[T gust.Digit](iter Iterator[T]) T

Product iterates over the entire iterator, multiplying all the elements

An empty iterator returns the one value of the type.

Panics

When calling Product() and a primitive integer type is being returned, method will panic if the computation overflows and overflow checks are enabled.

Examples

var factorial = func(n int) int {
	return Product(FromRange(1, n+1))
}
assert.Equal(t, 1, factorial(0))
assert.Equal(t, 1, factorial(1))
assert.Equal(t, 120, factorial(5))

func Pull2 added in v1.9.0

func Pull2[K any, V any](it Iterator[gust.Pair[K, V]]) (next func() (K, V, bool), stop func())

Pull2 converts the Iterator[gust.Pair[K, V]] to a pull-style iterator using Go's standard iter.Pull2. This returns two functions: next (to pull key-value pairs) and stop (to stop iteration). The caller should defer stop() to ensure proper cleanup.

Examples

iter1 := FromSlice([]int{1, 2, 3})
iter2 := FromSlice([]string{"a", "b", "c"})
zipped := Zip(iter1, iter2)
next, stop := Pull2(zipped)
defer stop()

// Pull key-value pairs manually
for {
	k, v, ok := next()
	if !ok {
		break
	}
	fmt.Println(k, v)
}

func Rfind added in v1.7.0

func Rfind[T any](de DoubleEndedIterator[T], predicate func(T) bool) gust.Option[T]

Rfind searches for an element of an iterator from the back that satisfies a predicate (function version).

Examples

var a = []int{1, 2, 3}
var deIter = FromSlice(a).MustToDoubleEnded()
assert.Equal(t, gust.Some(2), Rfind(deIter, func(x int) bool { return x == 2 }))

func Rfold

func Rfold[T any, B any](de DoubleEndedIterator[T], init B, f func(B, T) B) B

Rfold folds every element into an accumulator by applying an operation, starting from the back (generic version).

Examples

var a = []int{1, 2, 3}
var deIter = FromSlice(a).MustToDoubleEnded()
var sum = Rfold(deIter, 0, func(acc int, x int) int { return acc + x })
assert.Equal(t, 6, sum)

func Seq2 added in v1.9.0

func Seq2[K any, V any](it Iterator[gust.Pair[K, V]]) stditer.Seq2[K, V]

Seq2 converts the Iterator[gust.Pair[K, V]] to Go's standard iter.Seq2[K, V]. This allows using gust pair iterators with Go's built-in key-value iteration support.

Examples

// Convert Zip iterator to Go Seq2
iter1 := FromSlice([]int{1, 2, 3})
iter2 := FromSlice([]string{"a", "b", "c"})
zipped := Zip(iter1, iter2)
for k, v := range Seq2(zipped) {
	fmt.Println(k, v) // prints 1 a, 2 b, 3 c
}

// Works with Go's standard library functions
enumerated := Enumerate(FromSlice([]string{"a", "b", "c"}))
for idx, val := range Seq2(enumerated) {
	fmt.Println(idx, val) // prints 0 a, 1 b, 2 c
}

func Sum added in v1.7.0

func Sum[T gust.Digit](iter Iterator[T]) T

Sum sums the elements of an iterator.

Takes each element, adds them together, and returns the result.

An empty iterator returns the *additive identity* ("zero") of the type, which is 0 for integers and -0.0 for floats.

Panics

When calling Sum() and a primitive integer type is being returned, this method will panic if the computation overflows and overflow checks are enabled.

Examples

var a = []int{1, 2, 3}
var sum = Sum(FromSlice(a))
assert.Equal(t, 6, sum)

var b = []float64{}
var sumFloat = Sum(FromSlice(b))
assert.Equal(t, -0.0, sumFloat)

func TryFold

func TryFold[T any, B any](iter Iterator[T], init B, f func(B, T) gust.Result[B]) gust.Result[B]

TryFold is an iterator method that applies a function as long as it returns successfully, producing a single, final value.

TryFold() takes two arguments: an initial value, and a closure with two arguments: an 'accumulator', and an element. The closure either returns successfully, with the value that the accumulator should have for the next iteration, or it returns failure, with an error value that is propagated back to the caller immediately (short-circuiting).

The initial value is the value the accumulator will have on the first call. If applying the closure succeeded against every element of the iterator, TryFold() returns the final accumulator as success.

Folding is useful whenever you have a collection of something, and want to produce a single value from it.

Examples

Basic usage:

var a = []int{1, 2, 3}
// the checked sum of all of the elements of the array
var sum = TryFold(FromSlice(a), 0, func(acc int, x int) gust.Result[int] {
	// Simulate checked addition
	if acc > 100 {
		return gust.Err[int](errors.New("overflow"))
	}
	return gust.Ok(acc + x)
})
assert.True(t, sum.IsOk())
assert.Equal(t, 6, sum.Unwrap())

Short-circuiting:

var a = []int{10, 20, 30, 100, 40, 50}
var iter = FromSlice(a)
// This sum overflows when adding the 100 element
var sum = TryFold(iter, 0, func(acc int, x int) gust.Result[int] {
	if acc+x > 50 {
		return gust.Err[int](errors.New("overflow"))
	}
	return gust.Ok(acc + x)
})
assert.True(t, sum.IsErr())

func TryForEach added in v1.7.0

func TryForEach[T any, B any](iter Iterator[T], f func(T) gust.Result[B]) gust.Result[B]

TryForEach is an iterator method that applies a fallible function to each item in the iterator, stopping at the first error and returning that error.

This can also be thought of as the fallible form of ForEach() or as the stateless version of TryFold().

Examples

var data = []string{"no_tea.txt", "stale_bread.json", "torrential_rain.png"}
var res = TryForEach(FromSlice(data), func(x string) gust.Result[any] {
	fmt.Println(x)
	return gust.Ok[any](nil)
})
assert.True(t, res.IsOk())

func TryRfold

func TryRfold[T any, B any](de DoubleEndedIterator[T], init B, f func(B, T) gust.Result[B]) gust.Result[B]

TryRfold is the reverse version of TryFold: it takes elements starting from the back of the iterator (generic version).

Examples

var a = []string{"1", "2", "3"}
var deIter = FromSlice(a).MustToDoubleEnded()
var sum = TryRfold(deIter, 0, func(acc int, s string) gust.Result[int] {
	if v, err := strconv.Atoi(s); err == nil {
		return gust.Ok(acc + v)
	}
	return gust.Err[int](err)
})
assert.True(t, sum.IsOk())
assert.Equal(t, 6, sum.Unwrap())

func Unzip added in v1.7.0

func Unzip[T any, U any](iter Iterator[gust.Pair[T, U]]) ([]T, []U)

Unzip converts an iterator of pairs into a pair of containers.

Unzip() consumes an entire iterator of pairs, producing two collections: one from the left elements of the pairs, and one from the right elements.

This function is, in some sense, the opposite of Zip.

Examples

var a = []gust.Pair[int, string]{
	{A: 1, B: "a"},
	{A: 2, B: "b"},
	{A: 3, B: "c"},
}
var (left, right) = Unzip(FromSlice(a))
assert.Equal(t, []int{1, 2, 3}, left)
assert.Equal(t, []string{"a", "b", "c"}, right)

Types

type ChunkResult added in v1.10.0

type ChunkResult[T any] struct {
	// contains filtered or unexported fields
}

ChunkResult represents a success (T) or failure (T) for NextChunk. This is used when the error type is the same as the success type (e.g., []T).

func (ChunkResult[T]) IsErr added in v1.10.0

func (r ChunkResult[T]) IsErr() bool

IsErr returns true if the result is an error.

func (ChunkResult[T]) IsOk added in v1.10.0

func (r ChunkResult[T]) IsOk() bool

IsOk returns true if the result is ok.

func (ChunkResult[T]) Unwrap added in v1.10.0

func (r ChunkResult[T]) Unwrap() T

Unwrap returns the contained T value.

func (ChunkResult[T]) UnwrapErr added in v1.10.0

func (r ChunkResult[T]) UnwrapErr() T

UnwrapErr returns the contained error T value.

type DoubleEndedIterable added in v1.7.0

type DoubleEndedIterable[T any] interface {
	Iterable[T]                 // Includes Next() and SizeHint()
	gust.DoubleEndedIterable[T] // Includes NextBack() and Remaining()
}

DoubleEndedIterable is the interface for double-ended iterator implementations.

type DoubleEndedIterator added in v1.7.0

type DoubleEndedIterator[T any] struct {
	Iterator[T] // Embed Iterator to inherit all its methods
	// contains filtered or unexported fields
}

DoubleEndedIterator is the main double-ended iterator type that provides method chaining. It embeds Iterator[T] to inherit all Iterator methods, and adds double-ended specific methods. This enables Rust-like method chaining: deIter.Filter(...).NextBack().Rfold(...)

DoubleEndedIterator implements gust.Iterable[T] and gust.IterableSizeHint, so it can be used anywhere these interfaces are expected. It also inherits all Iterator[T] methods.

Examples

Basic usage:

var numbers = []int{1, 2, 3, 4, 5, 6}
var deIter = FromSlice(numbers).MustToDoubleEnded()

assert.Equal(t, gust.Some(1), deIter.Next())
assert.Equal(t, gust.Some(6), deIter.NextBack())
assert.Equal(t, gust.Some(5), deIter.NextBack())
assert.Equal(t, gust.Some(2), deIter.Next())
assert.Equal(t, gust.Some(3), deIter.Next())
assert.Equal(t, gust.Some(4), deIter.Next())
assert.Equal(t, gust.None[int](), deIter.Next())
assert.Equal(t, gust.None[int](), deIter.NextBack())

// Can use all Iterator methods:
var filtered = deIter.Filter(func(x int) bool { return x > 2 })
var collected = filtered.Collect()

func (DoubleEndedIterator[T]) AdvanceBackBy added in v1.7.0

func (de DoubleEndedIterator[T]) AdvanceBackBy(n uint) gust.Errable[uint]

AdvanceBackBy advances the iterator from the back by n elements.

AdvanceBackBy is the reverse version of AdvanceBy. This method will eagerly skip n elements starting from the back by calling NextBack up to n times until None is encountered.

AdvanceBackBy(n) will return NonErrable if the iterator successfully advances by n elements, or a ToErrable(k) with value k if None is encountered, where k is remaining number of steps that could not be advanced because the iterator ran out. If iter is empty and n is non-zero, then this returns ToErrable(n). Otherwise, k is always less than n.

Calling AdvanceBackBy(0) can do meaningful work.

Examples

var a = []int{3, 4, 5, 6}
var deIter = FromSlice(a).MustToDoubleEnded()
assert.Equal(t, gust.NonErrable[uint](), deIter.AdvanceBackBy(2))
assert.Equal(t, gust.Some(4), deIter.NextBack())
assert.Equal(t, gust.NonErrable[uint](), deIter.AdvanceBackBy(0))
assert.Equal(t, gust.ToErrable[uint](99), deIter.AdvanceBackBy(100))

func (DoubleEndedIterator[T]) NextBack added in v1.7.0

func (de DoubleEndedIterator[T]) NextBack() gust.Option[T]

NextBack removes and returns an element from the end of the iterator.

Returns None when there are no more elements.

Examples

var numbers = []int{1, 2, 3, 4, 5, 6}
var deIter = FromSlice(numbers).MustToDoubleEnded()
assert.Equal(t, gust.Some(6), deIter.NextBack())
assert.Equal(t, gust.Some(5), deIter.NextBack())
assert.Equal(t, gust.Some(4), deIter.NextBack())
assert.Equal(t, gust.Some(3), deIter.NextBack())
assert.Equal(t, gust.Some(2), deIter.NextBack())
assert.Equal(t, gust.Some(1), deIter.NextBack())
assert.Equal(t, gust.None[int](), deIter.NextBack())

func (DoubleEndedIterator[T]) NthBack added in v1.7.0

func (de DoubleEndedIterator[T]) NthBack(n uint) gust.Option[T]

NthBack returns the nth element from the end of the iterator.

This is essentially the reversed version of Nth(). Although like most indexing operations, the count starts from zero, so NthBack(0) returns the first value from the end, NthBack(1) the second, and so on.

Note that all elements between the end and the returned element will be consumed, including the returned element. This also means that calling NthBack(0) multiple times on the same iterator will return different elements.

NthBack() will return None if n is greater than or equal to the length of the iterator.

Examples

var a = []int{1, 2, 3}
var deIter = FromSlice(a).MustToDoubleEnded()
assert.Equal(t, gust.Some(1), deIter.NthBack(2))
assert.Equal(t, gust.Some(2), deIter.NthBack(1))
assert.Equal(t, gust.Some(3), deIter.NthBack(0))
assert.Equal(t, gust.None[int](), deIter.NthBack(10))

func (DoubleEndedIterator[T]) Remaining added in v1.8.0

func (de DoubleEndedIterator[T]) Remaining() uint

Remaining returns the number of elements remaining in the iterator.

Examples

var numbers = []int{1, 2, 3, 4, 5, 6} var deIter = FromSlice(numbers).MustToDoubleEnded() assert.Equal(t, uint(6), deIter.Remaining()) deIter.Next() assert.Equal(t, uint(5), deIter.Remaining()) deIter.NextBack() assert.Equal(t, uint(4), deIter.Remaining()) deIter.NextBack() assert.Equal(t, uint(3), deIter.Remaining()) deIter.NextBack() assert.Equal(t, uint(2), deIter.Remaining()) deIter.NextBack() assert.Equal(t, uint(1), deIter.Remaining()) deIter.NextBack() assert.Equal(t, uint(0), deIter.Remaining()) deIter.NextBack() assert.Equal(t, uint(0), deIter.Remaining())

func (DoubleEndedIterator[T]) Rfind added in v1.7.0

func (de DoubleEndedIterator[T]) Rfind(predicate func(T) bool) gust.Option[T]

Rfind searches for an element of an iterator from the back that satisfies a predicate.

Rfind() takes a closure that returns true or false. It applies this closure to each element of the iterator, starting at the end, and if any of them return true, then Rfind() returns Some(element). If they all return false, it returns None.

Rfind() is short-circuiting; in other words, it will stop processing as soon as the closure returns true.

Examples

var a = []int{1, 2, 3}
var deIter = FromSlice(a).MustToDoubleEnded()
assert.Equal(t, gust.Some(2), deIter.Rfind(func(x int) bool { return x == 2 }))

var b = []int{1, 2, 3}
var deIter2 = FromSlice(b).MustToDoubleEnded()
assert.Equal(t, gust.None[int](), deIter2.Rfind(func(x int) bool { return x == 5 }))

func (DoubleEndedIterator[T]) Rfold added in v1.7.0

func (de DoubleEndedIterator[T]) Rfold(init T, f func(T, T) T) T

Rfold folds every element into an accumulator by applying an operation, starting from the back.

This is the reverse version of Fold(): it takes elements starting from the back of the iterator.

Rfold() takes two arguments: an initial value, and a closure with two arguments: an 'accumulator', and an element. The closure returns the value that the accumulator should have for the next iteration.

The initial value is the value the accumulator will have on the first call.

After applying this closure to every element of the iterator, Rfold() returns the accumulator.

Note: Rfold() combines elements in a *right-associative* fashion. For associative operators like +, the order the elements are combined in is not important, but for non-associative operators like - the order will affect the final result.

Examples

var a = []int{1, 2, 3}
var deIter = FromSlice(a).MustToDoubleEnded()
var sum = deIter.Rfold(0, func(acc int, x int) int { return acc + x })
assert.Equal(t, 6, sum)

func (DoubleEndedIterator[T]) TryRfold added in v1.7.0

func (de DoubleEndedIterator[T]) TryRfold(init T, f func(T, T) gust.Result[T]) gust.Result[T]

TryRfold is the reverse version of TryFold: it takes elements starting from the back of the iterator.

Examples

var a = []string{"1", "2", "3"}
var deIter = FromSlice(a).MustToDoubleEnded()
var sum = deIter.TryRfold(0, func(acc int, s string) gust.Result[int] {
	if v, err := strconv.Atoi(s); err == nil {
		return gust.Ok(acc + v)
	}
	return gust.Err[int](err)
})
assert.True(t, sum.IsOk())
assert.Equal(t, 6, sum.Unwrap())

func (DoubleEndedIterator[T]) XRfold added in v1.7.0

func (de DoubleEndedIterator[T]) XRfold(init any, f func(any, T) any) any

XRfold folds every element into an accumulator by applying an operation, starting from the back (any version).

This is the reverse version of Fold(): it takes elements starting from the back of the iterator.

Examples

var a = []int{1, 2, 3}
var deIter = FromSlice(a).MustToDoubleEnded()
var deIter = iter.MustToDoubleEnded()
var sum = deIter.XRfold(0, func(acc any, x int) any { return acc.(int) + x })
assert.Equal(t, 6, sum)

func (DoubleEndedIterator[T]) XTryRfold added in v1.7.0

func (de DoubleEndedIterator[T]) XTryRfold(init any, f func(any, T) gust.Result[any]) gust.Result[any]

XTryRfold is the reverse version of TryFold: it takes elements starting from the back of the iterator (any version).

Examples

var a = []string{"1", "2", "3"}
var deIter = FromSlice(a).MustToDoubleEnded()
var sum = deIter.XTryRfold(0, func(acc any, s string) gust.Result[any] {
	if v, err := strconv.Atoi(s); err == nil {
		return gust.Ok(any(acc.(int) + v))
	}
	return gust.Err[any](err)
})
assert.True(t, sum.IsOk())
assert.Equal(t, 6, sum.Unwrap().(int))

type Iterable added in v1.7.0

type Iterable[T any] interface {
	gust.Iterable[T]
	gust.IterableSizeHint
}

Iterable is the interface that extends gust.Iterable[T] and gust.IterableSizeHint. This is used internally for concrete iterator implementations.

type Iterator

type Iterator[T any] struct {
	// contains filtered or unexported fields
}

Iterator is the main iterator type that provides method chaining. It wraps an Iterable[T] interface and provides all adapter methods as struct methods, enabling Rust-like method chaining: iter.Map(...).Filter(...).Collect()

Iterator implements gust.Iterable[T] and gust.IterableSizeHint, so it can be used anywhere these interfaces are expected.

Examples

var iter = FromSlice([]int{1, 2, 3, 4, 5})
var result = iter.Filter(func(x int) bool { return x > 2 }).
              Take(2).
              Collect()

func ArrayChunks added in v1.7.0

func ArrayChunks[T any](iter Iterator[T], chunkSize uint) Iterator[[]T]

func ChunkBy added in v1.7.0

func ChunkBy[T any](iter Iterator[T], predicate func(T, T) bool) Iterator[[]T]

func Cloned added in v1.7.0

func Cloned[T any](iter Iterator[*T]) Iterator[T]

Cloned creates an iterator which clones all of its elements. This function accepts Iterator[*T] and returns Iterator[T] for chainable calls.

func Empty added in v1.7.0

func Empty[T any]() Iterator[T]

Empty creates an iterator that yields no values.

Examples

var iter = Empty[int]()
assert.Equal(t, gust.None[int](), iter.Next())

func Enumerate

func Enumerate[T any](iter Iterator[T]) Iterator[gust.Pair[uint, T]]

Enumerate creates an iterator that yields pairs of (index, value). This function accepts Iterator[T] and returns Iterator[gust.Pair[uint, T]] for chainable calls.

func FilterMap

func FilterMap[T any, U any](iter Iterator[T], f func(T) gust.Option[U]) Iterator[U]

FilterMap creates an iterator that both filters and maps.

The returned iterator yields only the values for which the supplied closure returns gust.Some(value).

FilterMap can be used to make chains of Filter and Map more concise. The example below shows how a Map().Filter().Map() can be shortened to a single call to FilterMap.

Examples

Basic usage:

var a = []string{"1", "two", "NaN", "four", "5"}
var iter = FilterMap(FromSlice(a), func(s string) gust.Option[int] {
	if v, err := strconv.Atoi(s); err == nil {
		return gust.Some(v)
	}
	return gust.None[int]()
})

assert.Equal(t, gust.Some(1), iter.Next())
assert.Equal(t, gust.Some(5), iter.Next())
assert.Equal(t, gust.None[int](), iter.Next())

FilterMap creates an iterator that both filters and maps. This function accepts Iterator[T] and returns Iterator[U] for chainable calls.

func FlatMap added in v0.8.0

func FlatMap[T any, U any](iter Iterator[T], f func(T) Iterator[U]) Iterator[U]

FlatMap creates an iterator that works like map, but flattens nested structure.

The Map adapter is very useful, but only when the closure argument produces values. If it produces an iterator instead, there's an extra layer of indirection. FlatMap() will remove this extra layer on its own.

You can think of FlatMap(f) as the semantic equivalent of Mapping, and then Flattening as in Map(f).Flatten().

Another way of thinking about FlatMap(): Map's closure returns one item for each element, and FlatMap()'s closure returns an iterator for each element.

Examples

var words = []string{"alpha", "beta", "gamma"}
var iter = FlatMap(FromSlice(words), func(s string) Iterator[rune] {
	return FromSlice([]rune(s))
})
var result = Collect[rune](iter)
// result contains all characters from all words

func Flatten

func Flatten[T any](iter Iterator[Iterator[T]]) Iterator[T]

func FromElements

func FromElements[T any](elems ...T) Iterator[T]

FromElements creates an iterator from a set of elements.

Examples

var iter = FromElements(1, 2, 3)
assert.Equal(t, gust.Some(1), iter.Next())
assert.Equal(t, gust.Some(2), iter.Next())
assert.Equal(t, gust.Some(3), iter.Next())
assert.Equal(t, gust.None[int](), iter.Next())

func FromFunc added in v1.7.0

func FromFunc[T any](f func() gust.Option[T]) Iterator[T]

FromFunc creates an iterator from a function that generates values.

The function is called repeatedly until it returns gust.None[T]().

Examples

var count = 0
var iter = FromFunc(func() gust.Option[int] {
	if count < 3 {
		count++
		return gust.Some(count)
	}
	return gust.None[int]()
})
assert.Equal(t, gust.Some(1), iter.Next())
assert.Equal(t, gust.Some(2), iter.Next())
assert.Equal(t, gust.Some(3), iter.Next())
assert.Equal(t, gust.None[int](), iter.Next())

func FromIterable

func FromIterable[T any](data gust.Iterable[T]) Iterator[T]

FromIterable creates an iterator from a gust.Iterable[T]. If the data is already an Iterator[T], it returns the same iterator. If the data is an Iterable[T], it returns an Iterator[T] with the core. If the data is a gust.Iterable[T], it returns an Iterator[T] with the iterable wrapper.

Examples

var iter = FromIterable(FromSlice([]int{1, 2, 3}))
assert.Equal(t, gust.Some(1), iter.Next())
assert.Equal(t, gust.Some(2), iter.Next())
assert.Equal(t, gust.Some(3), iter.Next())
assert.Equal(t, gust.None[int](), iter.Next())

func FromPull added in v1.9.0

func FromPull[T any](next func() (T, bool), stop func()) (Iterator[T], func())

FromPull creates an Iterator[T] from a pull-style iterator (next and stop functions). This allows converting pull-style iterators to gust iterators. Returns the iterator and a deferStop function that should be deferred to ensure proper cleanup.

Note: While the sequence will automatically clean up when it ends naturally (when next() returns false), it is recommended to always use "defer deferStop()" to ensure proper cleanup in all cases, including early termination.

Examples

// Convert a pull-style iterator to gust Iterator
next, stop := iter.Pull(someSeq)
defer stop()
gustIter, deferStop := FromPull(next, stop)
defer deferStop()
result := gustIter.Filter(func(x int) bool { return x > 2 }).Collect()

// Works with custom pull-style iterators
customNext := func() (int, bool) {
	// custom implementation
	return 0, false
}
customStop := func() {}
gustIter, deferStop = FromPull(customNext, customStop)
defer deferStop()

func FromPull2 added in v1.9.0

func FromPull2[K any, V any](next func() (K, V, bool), stop func()) (Iterator[gust.Pair[K, V]], func())

FromPull2 creates an Iterator[gust.Pair[K, V]] from a pull-style iterator (next and stop functions). This allows converting pull-style key-value iterators to gust pair iterators. Returns the iterator and a deferStop function that should be deferred to ensure proper cleanup.

Note: While the sequence will automatically clean up when it ends naturally (when next() returns false), it is recommended to always use "defer deferStop()" to ensure proper cleanup in all cases, including early termination.

Examples

// Convert a pull-style iterator to gust Iterator
next, stop := iter.Pull2(someSeq2)
defer stop()
gustIter, deferStop := FromPull2(next, stop)
defer deferStop()
result := gustIter.Filter(func(p gust.Pair[int, string]) bool {
	return p.B != ""
}).Collect()

// Works with custom pull-style iterators
customNext := func() (int, string, bool) {
	// custom implementation
	return 0, "", false
}
customStop := func() {}
gustIter, deferStop = FromPull2(customNext, customStop)
defer deferStop()

func FromRange

func FromRange[T gust.Integer](start T, end T) Iterator[T]

FromRange creates an iterator from a range of integers.

The range is [start, end), meaning start is inclusive and end is exclusive.

Examples

var iter = FromRange(0, 5)
assert.Equal(t, gust.Some(0), iter.Next())
assert.Equal(t, gust.Some(1), iter.Next())
assert.Equal(t, gust.Some(2), iter.Next())
assert.Equal(t, gust.Some(3), iter.Next())
assert.Equal(t, gust.Some(4), iter.Next())
assert.Equal(t, gust.None[int](), iter.Next())

func FromSeq added in v1.9.0

func FromSeq[T any](seq stditer.Seq[T]) (Iterator[T], func())

FromSeq creates an Iterator[T] from Go's standard iter.Seq[T]. This allows converting Go standard iterators to gust iterators. Returns the iterator and a deferStop function that should be deferred to ensure proper cleanup.

Note: While the sequence will automatically clean up when it ends naturally (when next() returns false), it is recommended to always use "defer deferStop()" to ensure proper cleanup in all cases, including early termination.

Examples

// Convert a Go range iterator to gust Iterator
seq := func(yield func(int) bool) {
	for i := 0; i < 5; i++ {
		if !yield(i) {
			return
		}
	}
}
iter, deferStop := FromSeq(seq)
defer deferStop() // Recommended: ensures cleanup even if iteration ends naturally
assert.Equal(t, gust.Some(0), iter.Next())
assert.Equal(t, gust.Some(1), iter.Next())

// Works with Go's standard library iterators
iter, deferStop = FromSeq(iter.N(5)) // iter.N(5) returns iter.Seq[int]
defer deferStop()
assert.Equal(t, gust.Some(0), iter.Next())

func FromSeq2 added in v1.9.0

func FromSeq2[K any, V any](seq stditer.Seq2[K, V]) (Iterator[gust.Pair[K, V]], func())

FromSeq2 creates an Iterator[gust.Pair[K, V]] from Go's standard iter.Seq2[K, V]. This allows converting Go standard key-value iterators to gust pair iterators. Returns the iterator and a deferStop function that should be deferred to ensure proper cleanup.

Note: While the sequence will automatically clean up when it ends naturally (when next() returns false), it is recommended to always use "defer deferStop()" to ensure proper cleanup in all cases, including early termination.

Examples

// Convert a Go map iterator to gust Iterator
m := map[string]int{"a": 1, "b": 2, "c": 3}
seq2 := func(yield func(string, int) bool) {
	for k, v := range m {
		if !yield(k, v) {
			return
		}
	}
}
iter, deferStop := FromSeq2(seq2)
defer deferStop()
pair := iter.Next()
assert.True(t, pair.IsSome())
assert.Contains(t, []string{"a", "b", "c"}, pair.Unwrap().A)

// Works with Go's standard library iterators
iter, deferStop = FromSeq2(maps.All(myMap)) // maps.All returns iter.Seq2[K, V]
defer deferStop()

func FromSlice added in v1.7.0

func FromSlice[T any](slice []T) Iterator[T]

FromSlice creates an iterator from a slice.

The returned iterator supports double-ended iteration, allowing iteration from both ends. Use AsDoubleEnded() to convert to DoubleEndedIterator.

Examples

var a = []int{1, 2, 3}
var iter = FromSlice(a)
assert.Equal(t, gust.Some(1), iter.Next())
assert.Equal(t, gust.Some(2), iter.Next())
assert.Equal(t, gust.Some(3), iter.Next())
assert.Equal(t, gust.None[int](), iter.Next())

// As DoubleEndedIterator:
var deIter = AsDoubleEnded(FromSlice([]int{1, 2, 3, 4, 5, 6}))
assert.Equal(t, gust.Some(1), deIter.Next())
assert.Equal(t, gust.Some(6), deIter.NextBack())
assert.Equal(t, gust.Some(5), deIter.NextBack())

func Map

func Map[T any, U any](iter Iterator[T], f func(T) U) Iterator[U]

Map creates an iterator which calls a closure on each element.

Map() transforms one iterator into another, by means of its argument: something that implements a function. It produces a new iterator which calls this closure on each element of the original iterator.

If you are good at thinking in types, you can think of Map() like this: If you have an iterator that gives you elements of some type T, and you want an iterator of some other type U, you can use Map(), passing a closure that takes a T and returns a U.

Map() is conceptually similar to a for loop. However, as Map() is lazy, it is best used when you're already working with other iterators. If you're doing some sort of looping for a side effect, it's considered more idiomatic to use for than Map().

Examples

Basic usage:

var a = []int{1, 2, 3}
var iter = Map(FromSlice(a), func(x int) int { return 2 * x })

assert.Equal(t, gust.Some(2), iter.Next())
assert.Equal(t, gust.Some(4), iter.Next())
assert.Equal(t, gust.Some(6), iter.Next())
assert.Equal(t, gust.None[int](), iter.Next())

Map creates an iterator which calls a closure on each element. This function accepts Iterator[T] and returns Iterator[U] for chainable calls.

func MapWhile

func MapWhile[T any, U any](iter Iterator[T], predicate func(T) gust.Option[U]) Iterator[U]

MapWhile creates an iterator that both yields elements based on a predicate and maps.

MapWhile() takes a closure as an argument. It will call this closure on each element of the iterator, and yield elements while it returns gust.Some(_).

Examples

Basic usage:

var a = []int{-1, 4, 0, 1}
var iter = MapWhile(FromSlice(a), func(x int) gust.Option[int] {
	if x != 0 {
		return gust.Some(16 / x)
	}
	return gust.None[int]()
})

assert.Equal(t, gust.Some(-16), iter.Next())
assert.Equal(t, gust.Some(4), iter.Next())
assert.Equal(t, gust.None[int](), iter.Next())

func MapWindows added in v1.7.0

func MapWindows[T any, U any](iter Iterator[T], windowSize uint, f func([]T) U) Iterator[U]

MapWindows creates an iterator that applies a function to overlapping windows of a given size.

The windows are arrays of a fixed size that overlap. The first window contains the first N elements, the second window contains elements [1..N+1], etc.

Panics

Panics if window_size is 0 or if the iterator has fewer than window_size elements.

Examples

var iter = MapWindows(FromSlice([]int{1, 2, 3, 4, 5}), 3, func(window []int) int {
	return window[0] + window[1] + window[2]
})
assert.Equal(t, gust.Some(6), iter.Next())  // 1+2+3
assert.Equal(t, gust.Some(9), iter.Next())  // 2+3+4
assert.Equal(t, gust.Some(12), iter.Next()) // 3+4+5
assert.Equal(t, gust.None[int](), iter.Next())

func Once added in v1.7.0

func Once[T any](value T) Iterator[T]

Once creates an iterator that yields a single value.

Examples

Once creates an iterator that yields a value exactly once.

Examples

var iter = Once(42)
assert.Equal(t, gust.Some(42), iter.Next())
assert.Equal(t, gust.None[int](), iter.Next())

func OptMap added in v1.8.0

func OptMap[T any, U any](iter Iterator[T], f func(T) *U) Iterator[gust.Option[*U]]

OptMap creates an iterator which calls a closure on each element and returns a Option[*U]. NOTE:

`non-nil pointer` is wrapped as Some,
and `nil pointer` is wrapped as None.

Examples

iter := OptMap(FromSlice([]string{"1", "2", "3", "NaN"}), func(s string) *int {
	if v, err := strconv.Atoi(s); err == nil {
		return &v
	} else {
		return nil
	}
})

var newInt = func(v int) *int {
	return &v
}

assert.Equal(t, gust.Some(gust.Some(newInt(1))), iter.Next()) assert.Equal(t, gust.Some(gust.Some(newInt(2))), iter.Next()) assert.Equal(t, gust.Some(gust.Some(newInt(3))), iter.Next()) assert.Equal(t, gust.Some(gust.None[*int]()), iter.Next()) assert.Equal(t, gust.None[gust.Option[*int]](), iter.Next())

func Repeat added in v1.7.0

func Repeat[T any](value T) Iterator[T]

Repeat creates an iterator that repeats a value endlessly.

Examples

var iter = Repeat(42)
assert.Equal(t, gust.Some(42), iter.Next())
assert.Equal(t, gust.Some(42), iter.Next())
assert.Equal(t, gust.Some(42), iter.Next())
// ... continues forever

func RetMap added in v1.8.0

func RetMap[T any, U any](iter Iterator[T], f func(T) (U, error)) Iterator[gust.Result[U]]

assert.Equal(t, gust.Some(gust.Ok(1)), iter.Next()) assert.Equal(t, gust.Some(gust.Ok(2)), iter.Next()) assert.Equal(t, gust.Some(gust.Ok(3)), iter.Next()) assert.Equal(t, true, iter.Next().Unwrap().IsErr()) assert.Equal(t, gust.None[gust.Result[int]](), iter.Next())

func Scan added in v0.8.0

func Scan[T any, U any, St any](iter Iterator[T], initialState St, f func(*St, T) gust.Option[U]) Iterator[U]

Scan is an iterator adapter which, like Fold, holds internal state, but unlike Fold, produces a new iterator.

Scan() takes two arguments: an initial value which seeds the internal state, and a closure with two arguments, the first being a mutable reference to the internal state and the second an iterator element. The closure can assign to the internal state to share state between iterations.

On iteration, the closure will be applied to each element of the iterator and the return value from the closure, an gust.Option, is returned by the Next() method. Thus the closure can return gust.Some(value) to yield value, or gust.None[T]() to end the iteration.

Examples

var a = []int{1, 2, 3, 4}
var iter = Scan(FromSlice(a), 1, func(state *int, x int) gust.Option[int] {
	*state = *state * x
	if *state > 6 {
		return gust.None[int]()
	}
	return gust.Some(-*state)
})

assert.Equal(t, gust.Some(-1), iter.Next())
assert.Equal(t, gust.Some(-2), iter.Next())
assert.Equal(t, gust.Some(-6), iter.Next())
assert.Equal(t, gust.None[int](), iter.Next())

func Zip

func Zip[T any, U any](a Iterator[T], b Iterator[U]) Iterator[gust.Pair[T, U]]

Zip 'zips up' two iterators into a single iterator of pairs.

Zip() returns a new iterator that will iterate over two other iterators, returning a tuple where the first element comes from the first iterator, and the second element comes from the second iterator.

In other words, it zips two iterators together, into a single one.

If either iterator returns gust.None[T](), Next() from the zipped iterator will return gust.None[T]().

Examples

Basic usage:

var s1 = FromSlice([]rune{'a', 'b', 'c'})
var s2 = FromSlice([]rune{'d', 'e', 'f'})
var iter = Zip(s1, s2)

assert.Equal(t, gust.Some(gust.Pair[rune, rune]{A: 'a', B: 'd'}), iter.Next())
assert.Equal(t, gust.Some(gust.Pair[rune, rune]{A: 'b', B: 'e'}), iter.Next())
assert.Equal(t, gust.Some(gust.Pair[rune, rune]{A: 'c', B: 'f'}), iter.Next())
assert.Equal(t, gust.None[gust.Pair[rune, rune]](), iter.Next())

Zip creates an iterator that zips two iterators together. This function accepts Iterator[T] and Iterator[U] and returns Iterator[gust.Pair[T, U]] for chainable calls.

func (Iterator[T]) AdvanceBy

func (it Iterator[T]) AdvanceBy(n uint) gust.Errable[uint]

AdvanceBy advances the iterator by n elements.

Examples

var iter = FromSlice([]int{1, 2, 3, 4})
assert.Equal(t, gust.NonErrable[uint](), iter.AdvanceBy(2))

func (Iterator[T]) All

func (it Iterator[T]) All(predicate func(T) bool) bool

All tests if all elements satisfy a predicate.

Examples

var iter = FromSlice([]int{2, 4, 6})
assert.True(t, iter.All(func(x int) bool { return x%2 == 0 }))

func (Iterator[T]) Any

func (it Iterator[T]) Any(predicate func(T) bool) bool

Any tests if any element satisfies a predicate.

Examples

var iter = FromSlice([]int{1, 2, 3})
assert.True(t, iter.Any(func(x int) bool { return x > 2 }))

func (Iterator[T]) Chain

func (it Iterator[T]) Chain(other Iterator[T]) Iterator[T]

Chain takes two iterators and creates a new iterator over both in sequence.

Examples

var iter1 = FromSlice([]int{1, 2, 3})
var iter2 = FromSlice([]int{4, 5, 6})
var chained = iter1.Chain(iter2)
assert.Equal(t, gust.Some(1), chained.Next())

func (Iterator[T]) Collect

func (it Iterator[T]) Collect() []T

Collect collects all items into a slice.

Examples

var iter = FromSlice([]int{1, 2, 3})
var result = iter.Collect()
assert.Equal(t, []int{1, 2, 3}, result)

func (Iterator[T]) Count

func (it Iterator[T]) Count() uint

Count consumes the iterator, counting the number of iterations.

Examples

var iter = FromSlice([]int{1, 2, 3, 4, 5})
assert.Equal(t, uint(5), iter.Count())

func (Iterator[T]) Cycle added in v1.7.0

func (it Iterator[T]) Cycle() Iterator[T]

Cycle repeats an iterator endlessly.

Examples

var iter = FromSlice([]int{1, 2, 3})
var cycled = iter.Cycle()
assert.Equal(t, gust.Some(1), cycled.Next())
assert.Equal(t, gust.Some(2), cycled.Next())
assert.Equal(t, gust.Some(3), cycled.Next())
assert.Equal(t, gust.Some(1), cycled.Next()) // starts over

func (Iterator[T]) Filter

func (it Iterator[T]) Filter(predicate func(T) bool) Iterator[T]

Filter creates an iterator which uses a closure to determine if an element should be yielded.

Examples

var iter = FromSlice([]int{0, 1, 2})
var filtered = iter.Filter(func(x int) bool { return x > 0 })
assert.Equal(t, gust.Some(1), filtered.Next())

func (Iterator[T]) FilterMap

func (it Iterator[T]) FilterMap(f func(T) gust.Option[T]) Iterator[T]

FilterMap creates an iterator that both filters and maps.

Examples

var iter = FromSlice([]string{"1", "two", "NaN", "four", "5"})
var filtered = iter.FilterMap(func(s string) gust.Option[string] {
	if s == "1" || s == "5" {
		return gust.Some(s)
	}
	return gust.None[string]()
})
// Can chain: filtered.Filter(...).Collect()

func (Iterator[T]) Find

func (it Iterator[T]) Find(predicate func(T) bool) gust.Option[T]

Find searches for an element that satisfies a predicate.

Examples

var iter = FromSlice([]int{1, 2, 3})
assert.Equal(t, gust.Some(2), iter.Find(func(x int) bool { return x > 1 }))

func (Iterator[T]) FindMap

func (it Iterator[T]) FindMap(f func(T) gust.Option[T]) gust.Option[T]

FindMap searches for an element and maps it.

Examples

var iter = FromSlice([]string{"lol", "NaN", "2", "5"})
var firstNumber = iter.FindMap(func(s string) gust.Option[int] {
	if v, err := strconv.Atoi(s); err == nil {
		return gust.Some(v)
	}
	return gust.None[int]()
})
assert.Equal(t, gust.Some(2), firstNumber)

func (Iterator[T]) FlatMap added in v1.7.0

func (it Iterator[T]) FlatMap(f func(T) Iterator[T]) Iterator[T]

FlatMap creates an iterator that maps and flattens nested iterators.

Examples

var iter = FromSlice([]int{1, 2, 3})
var flatMapped = iter.FlatMap(func(x int) Iterator[int] {
	return FromSlice([]int{x, x * 2})
})
// Can chain: flatMapped.Filter(...).Collect()

func (Iterator[T]) Fold

func (it Iterator[T]) Fold(init T, f func(T, T) T) T

Fold folds every element into an accumulator. This wrapper method allows Fold to be called as a method.

Examples

var iter = FromSlice([]int{1, 2, 3})
var sum = iter.Fold(0, func(acc int, x int) int { return acc + x })
assert.Equal(t, 6, sum)

func (Iterator[T]) ForEach

func (it Iterator[T]) ForEach(f func(T))

ForEach calls a closure on each element.

Examples

var iter = FromSlice([]int{1, 2, 3})
iter.ForEach(func(x int) { fmt.Println(x) })

func (Iterator[T]) Fuse

func (it Iterator[T]) Fuse() Iterator[T]

Fuse creates an iterator that ends after the first None.

Examples

var iter = FromSlice([]int{1, 2, 3})
var fused = iter.Fuse()
// After None, it will always return None

func (Iterator[T]) Inspect

func (it Iterator[T]) Inspect(f func(T)) Iterator[T]

Inspect creates an iterator that calls a closure on each element for side effects.

Examples

var iter = FromSlice([]int{1, 2, 3})
var inspected = iter.Inspect(func(x int) { fmt.Println(x) })
// Prints 1, 2, 3 when iterated

func (Iterator[T]) Intersperse

func (it Iterator[T]) Intersperse(separator T) Iterator[T]

Intersperse creates an iterator that places a separator between adjacent items.

Examples

var iter = FromSlice([]int{0, 1, 2})
var interspersed = iter.Intersperse(100)
assert.Equal(t, gust.Some(0), interspersed.Next())
assert.Equal(t, gust.Some(100), interspersed.Next())

func (Iterator[T]) IntersperseWith

func (it Iterator[T]) IntersperseWith(separator func() T) Iterator[T]

IntersperseWith creates an iterator that places an item generated by separator between adjacent items.

Examples

var iter = FromSlice([]int{0, 1, 2})
var interspersed = iter.IntersperseWith(func() int { return 99 })
assert.Equal(t, gust.Some(0), interspersed.Next())
assert.Equal(t, gust.Some(99), interspersed.Next())

func (Iterator[T]) Last

func (it Iterator[T]) Last() gust.Option[T]

Last returns the last element of the iterator.

Examples

var iter = FromSlice([]int{1, 2, 3})
assert.Equal(t, gust.Some(3), iter.Last())

func (Iterator[T]) Map

func (it Iterator[T]) Map(f func(T) T) Iterator[T]

Map creates an iterator which calls a closure on each element.

Examples

var iter = FromSlice([]int{1, 2, 3})
var doubled = iter.Map(func(x int) int { return x * 2 })
assert.Equal(t, gust.Some(2), doubled.Next())
// Can chain: doubled.Filter(...).Collect()

func (Iterator[T]) MapWhile

func (it Iterator[T]) MapWhile(predicate func(T) gust.Option[T]) Iterator[T]

MapWhile creates an iterator that both yields elements based on a predicate and maps.

func (Iterator[T]) MapWindows added in v1.7.0

func (it Iterator[T]) MapWindows(windowSize uint, f func([]T) T) Iterator[T]

MapWindows creates an iterator that applies a function to overlapping windows.

Examples

var iter = FromSlice([]int{1, 2, 3, 4, 5})
var windows = iter.MapWindows(3, func(window []int) int {
	return window[0] + window[1] + window[2]
})
// Can chain: windows.Filter(...).Collect()

func (Iterator[T]) MaxBy added in v1.7.0

func (it Iterator[T]) MaxBy(compare func(T, T) int) gust.Option[T]

MaxBy returns the element that gives the maximum value with respect to the specified comparison function.

Examples

var iter = FromSlice([]int{-3, 0, 1, 5, -10})
var max = iter.MaxBy(func(x, y int) int {
	if x < y {
		return -1
	}
	if x > y {
		return 1
	}
	return 0
})
assert.Equal(t, gust.Some(5), max)

func (Iterator[T]) MinBy added in v1.7.0

func (it Iterator[T]) MinBy(compare func(T, T) int) gust.Option[T]

MinBy returns the element that gives the minimum value with respect to the specified comparison function.

Examples

var iter = FromSlice([]int{-3, 0, 1, 5, -10})
var min = iter.MinBy(func(x, y int) int {
	if x < y {
		return -1
	}
	if x > y {
		return 1
	}
	return 0
})
assert.Equal(t, gust.Some(-10), min)

func (Iterator[T]) MustToDoubleEnded added in v1.7.0

func (it Iterator[T]) MustToDoubleEnded() DoubleEndedIterator[T]

MustToDoubleEnded converts to a DoubleEndedIterator[T] if the underlying iterator supports double-ended iteration. Otherwise, it panics.

Examples

var iter = FromSlice([]int{1, 2, 3})
var deIter = iter.MustToDoubleEnded()
assert.Equal(t, gust.Some(3), deIter.NextBack())
// Can use Iterator methods:
var doubled = deIter.Map(func(x int) any { return x * 2 })

func (Iterator[T]) Next

func (it Iterator[T]) Next() gust.Option[T]

Next advances the iterator and returns the next value. This implements gust.Iterable[T] interface.

func (Iterator[T]) NextChunk

func (it Iterator[T]) NextChunk(n uint) ChunkResult[[]T]

NextChunk advances the iterator and returns an array containing the next N values.

Examples

var iter = FromSlice([]int{1, 2, 3, 4, 5})
chunk := iter.NextChunk(2)
assert.True(t, chunk.IsOk())

func (Iterator[T]) Nth

func (it Iterator[T]) Nth(n uint) gust.Option[T]

Nth returns the nth element of the iterator.

Examples

var iter = FromSlice([]int{1, 2, 3})
assert.Equal(t, gust.Some(2), iter.Nth(1))

func (Iterator[T]) Partition added in v1.0.0

func (it Iterator[T]) Partition(f func(T) bool) (truePart []T, falsePart []T)

Partition partitions the iterator into two slices.

Examples

var iter = FromSlice([]int{1, 2, 3, 4, 5})
evens, odds := iter.Partition(func(x int) bool { return x%2 == 0 })
assert.Equal(t, []int{2, 4}, evens)
assert.Equal(t, []int{1, 3, 5}, odds)

func (Iterator[T]) Peekable

func (it Iterator[T]) Peekable() PeekableIterator[T]

Peekable creates a peekable iterator.

Examples

var iter = FromSlice([]int{1, 2, 3})
var peekable = iter.Peekable()
assert.Equal(t, gust.Some(1), peekable.Peek())
assert.Equal(t, gust.Some(1), peekable.Next())

// Can use all Iterator methods:
var filtered = peekable.Filter(func(x int) bool { return x > 1 })
assert.Equal(t, gust.Some(2), filtered.Next())

func (Iterator[T]) Position

func (it Iterator[T]) Position(predicate func(T) bool) gust.Option[uint]

Position searches for an element in an iterator, returning its index.

Examples

var iter = FromSlice([]int{1, 2, 3})
assert.Equal(t, gust.Some(uint(1)), iter.Position(func(x int) bool { return x == 2 }))

func (Iterator[T]) Pull added in v1.9.0

func (it Iterator[T]) Pull() (next func() (T, bool), stop func())

Pull converts the Iterator[T] to a pull-style iterator using Go's standard iter.Pull. This returns two functions: next (to pull values) and stop (to stop iteration). The caller should defer stop() to ensure proper cleanup.

Examples

iter := FromSlice([]int{1, 2, 3, 4, 5})
next, stop := iter.Pull()
defer stop()

// Pull values manually
for {
	v, ok := next()
	if !ok {
		break
	}
	fmt.Println(v)
	if v == 3 {
		break // Early termination
	}
}

func (Iterator[T]) Pull2 added in v1.9.1

func (it Iterator[T]) Pull2() (next func() (uint, T, bool), stop func())

Pull2 converts the Iterator[T] to a pull-style iterator using Go's standard iter.Pull2. This returns two functions: next (to pull key-value pairs) and stop (to stop iteration). The caller should defer stop() to ensure proper cleanup.

Examples

iter := FromSlice([]int{1, 2, 3, 4, 5})
next, stop := iter.Pull2()
defer stop()

// Pull key-value pairs manually
for {
	k, v, ok := next()
	if !ok {
		break
	}
	fmt.Println(k, v)
	if v == 3 {
		break // Early termination
	}
}

func (Iterator[T]) Reduce

func (it Iterator[T]) Reduce(f func(T, T) T) gust.Option[T]

Reduce reduces the iterator to a single value.

Examples

var iter = FromSlice([]int{1, 2, 3})
var sum = iter.Reduce(func(acc int, x int) int { return acc + x })
assert.Equal(t, gust.Some(6), sum)

func (Iterator[T]) Scan added in v0.8.0

func (it Iterator[T]) Scan(initialState T, f func(*T, T) gust.Option[T]) Iterator[T]

Scan creates an iterator that scans over the iterator with a state.

Examples

var iter = FromSlice([]int{1, 2, 3})
var scanned = iter.Scan(0, func(state *int, x int) gust.Option[int] {
	*state = *state + x
	return gust.Some(*state)
})
// Can chain: scanned.Filter(...).Collect()

func (Iterator[T]) Seq added in v1.9.0

func (it Iterator[T]) Seq() stditer.Seq[T]

Seq converts the Iterator[T] to Go's standard iter.Seq[T]. This allows using gust iterators with Go's built-in iteration support (for loops).

Examples

iter := FromSlice([]int{1, 2, 3})
for v := range iter.Seq() {
	fmt.Println(v) // prints 1, 2, 3
}

func (Iterator[T]) Seq2 added in v1.9.1

func (it Iterator[T]) Seq2() stditer.Seq2[uint, T]

Seq2 converts the Iterator[T] to Go's standard iter.Seq2[T]. This allows using gust iterators with Go's built-in iteration support (for loops).

Examples

iter := FromSlice([]int{1, 2, 3})

for k, v := range iter.Seq2() {
	fmt.Println(k, v) // prints 0 1, 1 2, 2 3
}

func (Iterator[T]) SizeHint

func (it Iterator[T]) SizeHint() (uint, gust.Option[uint])

SizeHint returns the bounds on the remaining length of the iterator. This implements gust.IterableSizeHint interface.

func (Iterator[T]) Skip added in v0.8.0

func (it Iterator[T]) Skip(n uint) Iterator[T]

Skip creates an iterator that skips the first n elements.

Examples

var iter = FromSlice([]int{1, 2, 3, 4, 5})
var skipped = iter.Skip(2)
assert.Equal(t, gust.Some(3), skipped.Next())

func (Iterator[T]) SkipWhile

func (it Iterator[T]) SkipWhile(predicate func(T) bool) Iterator[T]

SkipWhile creates an iterator that skips elements while a predicate is true.

Examples

var iter = FromSlice([]int{1, 2, 3, 4, 5})
var skipped = iter.SkipWhile(func(x int) bool { return x < 3 })
assert.Equal(t, gust.Some(3), skipped.Next())

func (Iterator[T]) StepBy

func (it Iterator[T]) StepBy(step uint) Iterator[T]

StepBy creates an iterator that steps by n elements at a time.

Examples

var iter = FromSlice([]int{0, 1, 2, 3, 4, 5})
var stepped = iter.StepBy(2)
assert.Equal(t, gust.Some(0), stepped.Next())
assert.Equal(t, gust.Some(2), stepped.Next())
assert.Equal(t, gust.Some(4), stepped.Next())

func (Iterator[T]) Take added in v0.8.0

func (it Iterator[T]) Take(n uint) Iterator[T]

Take creates an iterator that yields the first n elements.

Examples

var iter = FromSlice([]int{1, 2, 3, 4, 5})
var taken = iter.Take(2)
assert.Equal(t, gust.Some(1), taken.Next())
assert.Equal(t, gust.Some(2), taken.Next())
assert.Equal(t, gust.None[int](), taken.Next())

func (Iterator[T]) TakeWhile

func (it Iterator[T]) TakeWhile(predicate func(T) bool) Iterator[T]

TakeWhile creates an iterator that yields elements while a predicate is true.

Examples

var iter = FromSlice([]int{1, 2, 3, 4, 5})
var taken = iter.TakeWhile(func(x int) bool { return x < 3 })
assert.Equal(t, gust.Some(1), taken.Next())
assert.Equal(t, gust.Some(2), taken.Next())
assert.Equal(t, gust.None[int](), taken.Next())

func (Iterator[T]) TryFind

func (it Iterator[T]) TryFind(f func(T) gust.Result[bool]) gust.Result[gust.Option[T]]

TryFind applies function to the elements of iterator and returns the first true result or the first error.

Examples

var a = []string{"1", "2", "lol", "NaN", "5"}
var result = iter.TryFind(func(s string) gust.Result[bool] {
	if s == "lol" {
		return gust.Err[bool](errors.New("invalid"))
	}
	if v, err := strconv.Atoi(s); err == nil {
		return gust.Ok(v == 2)
	}
	return gust.Ok(false)
})
assert.True(t, result.IsOk())

func (Iterator[T]) TryFold

func (it Iterator[T]) TryFold(init T, f func(T, T) gust.Result[T]) gust.Result[T]

TryFold applies a function as long as it returns successfully, producing a single, final value.

Examples

var iter = FromSlice([]int{1, 2, 3})
var sum = iter.TryFold(0, func(acc int, x int) gust.Result[int] {
	return gust.Ok(acc + x)
})
assert.True(t, sum.IsOk())
assert.Equal(t, 6, sum.Unwrap())

func (Iterator[T]) TryForEach added in v1.0.0

func (it Iterator[T]) TryForEach(f func(T) gust.Result[T]) gust.Result[T]

TryForEach applies a fallible function to each item in the iterator, stopping at the first error and returning that error.

Examples

var data = []string{"no_tea.txt", "stale_bread.json", "torrential_rain.png"}
var res = iter.TryForEach(func(x string) gust.Result[string] {
	fmt.Println(x)
	return gust.Ok[string](x+"_processed")
})
assert.True(t, res.IsOk())
assert.Equal(t, "no_tea.txt_processed", res.Unwrap())

func (Iterator[T]) TryReduce added in v1.0.0

func (it Iterator[T]) TryReduce(f func(T, T) gust.Result[T]) gust.Result[gust.Option[T]]

TryReduce reduces the elements to a single one by repeatedly applying a reducing operation.

Examples

var numbers = []int{10, 20, 5, 23, 0}
var sum = iter.TryReduce(func(x, y int) gust.Result[int] {
	if x+y > 100 {
		return gust.Err[int](errors.New("overflow"))
	}
	return gust.Ok(x + y)
})
assert.True(t, sum.IsOk())

func (Iterator[T]) TryToDoubleEnded added in v1.7.0

func (it Iterator[T]) TryToDoubleEnded() gust.Option[DoubleEndedIterator[T]]

TryToDoubleEnded converts to a DoubleEndedIterator[T] if the underlying iterator supports double-ended iteration. Otherwise, it returns None.

Examples

var iter = FromSlice([]int{1, 2, 3})
var deIter = iter.TryToDoubleEnded()
assert.Equal(t, gust.Some(3), deIter.NextBack())
// Can use Iterator methods:
var doubled = deIter.Map(func(x int) any { return x * 2 })

func (Iterator[T]) XFilterMap

func (it Iterator[T]) XFilterMap(f func(T) gust.Option[any]) Iterator[any]

XFilterMap creates an iterator that both filters and maps (any version).

Examples

var iter = FromSlice([]string{"1", "two", "NaN", "four", "5"})
var filtered = iter.XFilterMap(func(s string) gust.Option[any] {
	if s == "1" {
		return gust.Some(any(1))
	}
	if s == "5" {
		return gust.Some(any(5))
	}
	return gust.None[any]()
})
// Can chain: filtered.Filter(...).Collect()

func (Iterator[T]) XFindMap

func (it Iterator[T]) XFindMap(f func(T) gust.Option[any]) gust.Option[any]

XFindMap searches for an element and maps it (any version).

Examples

var iter = FromSlice([]string{"lol", "NaN", "2", "5"})
var firstNumber = iter.XFindMap(func(s string) gust.Option[any] {
	if v, err := strconv.Atoi(s); err == nil {
		return gust.Some(any(v))
	}
	return gust.None[any]()
})
assert.True(t, firstNumber.IsSome())
assert.Equal(t, 2, firstNumber.Unwrap().(int))

func (Iterator[T]) XFlatMap added in v1.7.0

func (it Iterator[T]) XFlatMap(f func(T) Iterator[any]) Iterator[any]

XFlatMap creates an iterator that maps and flattens nested iterators (any version).

Examples

var iter = FromSlice([]int{1, 2, 3})
var flatMapped = iter.XFlatMap(func(x int) Iterator[any] {
	return FromSlice([]any{x, x * 2})
})
// Can chain: flatMapped.Filter(...).Collect()

func (Iterator[T]) XFold added in v1.7.0

func (it Iterator[T]) XFold(init any, f func(any, T) any) any

XFold folds every element into an accumulator. This wrapper method allows XFold to be called as a method.

Examples

var iter = FromSlice([]int{1, 2, 3})
var sum = iter.XFold(0, func(acc any, x int) any { return acc.(int) + x })
assert.Equal(t, 6, sum)

func (Iterator[T]) XMap

func (it Iterator[T]) XMap(f func(T) any) Iterator[any]

XMap creates an iterator which calls a closure on each element (any version).

Examples

var iter = FromSlice([]int{1, 2, 3})
var doubled = iter.XMap(func(x int) any { return x * 2 })
assert.Equal(t, gust.Some(2), doubled.Next())
// Can chain: doubled.Filter(...).Collect()

func (Iterator[T]) XMapWhile

func (it Iterator[T]) XMapWhile(predicate func(T) gust.Option[any]) Iterator[any]

XMapWhile creates an iterator that both yields elements based on a predicate and maps (any version).

func (Iterator[T]) XMapWindows added in v1.7.0

func (it Iterator[T]) XMapWindows(windowSize uint, f func([]T) any) Iterator[any]

XMapWindows creates an iterator that applies a function to overlapping windows (any version).

Examples

var iter = FromSlice([]int{1, 2, 3, 4, 5})
var windows = iter.XMapWindows(3, func(window []int) any {
	return window[0] + window[1] + window[2]
})
// Can chain: windows.Filter(...).Collect()

func (Iterator[T]) XScan added in v1.7.0

func (it Iterator[T]) XScan(initialState any, f func(*any, T) gust.Option[any]) Iterator[any]

XScan creates an iterator that scans over the iterator with a state (any version).

Examples

var iter = FromSlice([]int{1, 2, 3})
var scanned = iter.XScan(0, func(state *any, x int) gust.Option[any] {
	s := (*state).(int) + x
	*state = s
	return gust.Some(any(s))
})
// Can chain: scanned.Filter(...).Collect()

func (Iterator[T]) XTryFold added in v1.7.0

func (it Iterator[T]) XTryFold(init any, f func(any, T) gust.Result[any]) gust.Result[any]

XTryFold applies a function as long as it returns successfully, producing a single, final value (any version).

Examples

var iter = FromSlice([]int{1, 2, 3})
var sum = iter.XTryFold(0, func(acc any, x int) gust.Result[any] {
	return gust.Ok(any(acc.(int) + x))
})
assert.True(t, sum.IsOk())
assert.Equal(t, 6, sum.Unwrap().(int))

func (Iterator[T]) XTryForEach added in v1.7.0

func (it Iterator[T]) XTryForEach(f func(T) gust.Result[any]) gust.Result[any]

XTryForEach applies a fallible function to each item in the iterator, stopping at the first error and returning that error.

Examples

var data = []string{"no_tea.txt", "stale_bread.json", "torrential_rain.png"}
var res = iter.TryForEach(func(x string) gust.Result[any] {
	fmt.Println(x)
	return gust.Ok[any](nil)
})
assert.True(t, res.IsOk())

type PeekableIterator

type PeekableIterator[T any] struct {
	Iterator[T] // Embed Iterator to inherit all its methods
	// contains filtered or unexported fields
}

PeekableIterator is an iterator that supports peeking at the next element. It embeds Iterator[T] to inherit all Iterator methods, and adds Peek() method.

Examples

var xs = []int{1, 2, 3}
var iter = Peekable(FromSlice(xs))

// peek() lets us see into the future
assert.Equal(t, gust.Some(1), iter.Peek())
assert.Equal(t, gust.Some(1), iter.Next())

// Can use all Iterator methods:
var filtered = iter.Filter(func(x int) bool { return x > 1 })
assert.Equal(t, gust.Some(2), filtered.Next())

func (*PeekableIterator[T]) Next added in v1.7.0

func (p *PeekableIterator[T]) Next() gust.Option[T]

Next advances the iterator and returns the next value. This overrides Iterator[T].Next() to handle peeked values.

func (*PeekableIterator[T]) Peek added in v1.7.0

func (p *PeekableIterator[T]) Peek() gust.Option[T]

Peek returns the next element without consuming it.

Examples

var xs = []int{1, 2, 3}
var iter = Peekable(FromSlice(xs))

assert.Equal(t, gust.Some(1), iter.Peek())
assert.Equal(t, gust.Some(1), iter.Peek()) // Can peek multiple times
assert.Equal(t, gust.Some(1), iter.Next())

func (*PeekableIterator[T]) SizeHint added in v1.7.0

func (p *PeekableIterator[T]) SizeHint() (uint, gust.Option[uint])

SizeHint returns the bounds on the remaining length of the iterator. This overrides Iterator[T].SizeHint() to account for peeked values.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL