enumerators

package module
v0.1.0-alpha.30 Latest Latest
Warning

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

Go to latest
Published: Jul 3, 2025 License: MIT Imports: 6 Imported by: 26

README

Dependabot Updates ci

enumerators

A small utility library for defining and consuming enumerators in Go. It provides a consistent interface to iterate over slices, channels, and custom generators.

Installation

go get github.com/fgrzl/enumerators

Overview

This library defines a generic Enumerator[T] interface with concrete implementations for common data sources:

  • Slices
  • Channels
  • Callback-based generators

Interface

type Enumerator[T any] interface {
  MoveNext() bool
  Current() (T, error)
  Err() error
}

Built-in Enumerators

SliceEnumerator

Iterates over a Go slice.

e := enumerators.NewSliceEnumerator([]int{1, 2, 3})
for e.MoveNext() {
  v, _ := e.Current()
  fmt.Println(v)
}
ChannelEnumerator

Iterates over a channel until it's closed.

ch := make(chan string)
go func() {
  ch <- "hello"
  ch <- "world"
  close(ch)
}()

e := enumerators.NewChannelEnumerator(ch)
for e.MoveNext() {
  v, _ := e.Current()
  fmt.Println(v)
}

Documentation

Overview

Package enumerators provides generic iterator utilities such as chunking, mapping, and cleanup behavior for stream-like processing.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Cleanup

func Cleanup[T any](enumerator Enumerator[T], cleanup func()) *cleanupEnumerator[T]

Cleanup wraps an enumerator with a cleanup function that runs on Dispose.

func Collect

func Collect[T any](enumerator Enumerator[Enumerator[T]]) ([][]T, error)

Collect gathers all chunks into a slice of slices

func Consume

func Consume[T any](e Enumerator[T]) error

Consume advances the enumerator to completion and disposes it. It returns any error encountered during iteration.

func ForEach

func ForEach[T any](enumerator Enumerator[T], do func(T) error) error

func Sum

func Sum[T any, TSum constraints.Ordered](enumerator Enumerator[T], selector func(item T) (TSum, error)) (TSum, error)

Sum creates an enumerator that returns the sum of elements

func ToMap

func ToMap[T any, TKey comparable, TValue any](enumerator Enumerator[T], keyFn func(T) TKey, valFn func(T) TValue) (map[TKey]TValue, error)

ToMap iterates over the provided enumerator and builds a map by applying the keyFn and valFn to each item. The resulting map uses the key from keyFn(item) and the value from valFn(item). If the enumerator yields an error during iteration, the function returns immediately with that error.

The enumerator is disposed automatically at the end of processing.

Returns an error if iteration fails. If the enumerator is nil, returns nil, nil.

func ToMapWithKey

func ToMapWithKey[TKey comparable, TValue any](enumerator Enumerator[TValue], keyFn func(TValue) TKey) (map[TKey]TValue, error)

ToMapWithKey iterates over the provided enumerator and builds a map using each item as the value. The key for each entry is computed by applying keyFn(item).

The enumerator is disposed automatically at the end of processing.

Returns an error if iteration fails. If the enumerator is nil, returns nil, nil.

func ToSlice

func ToSlice[T any](enumerator Enumerator[T]) ([]T, error)

Types

type ChannelEnumerator

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

func Channel

func Channel[T any](ctx context.Context, size int) *ChannelEnumerator[T]

Channel creates a new channel-based enumerator.

func (*ChannelEnumerator[T]) Complete

func (e *ChannelEnumerator[T]) Complete()

Complete signals that no more values will be published.

func (*ChannelEnumerator[T]) Current

func (e *ChannelEnumerator[T]) Current() (T, error)

Current returns the current value and any error encountered.

func (*ChannelEnumerator[T]) Dispose

func (e *ChannelEnumerator[T]) Dispose()

Dispose cleans up resources and signals termination.

func (*ChannelEnumerator[T]) Err

func (e *ChannelEnumerator[T]) Err() error

Err returns any error encountered during enumeration.

func (*ChannelEnumerator[T]) Error

func (e *ChannelEnumerator[T]) Error(err error)

Error signals an error to the enumerator.

func (*ChannelEnumerator[T]) MoveNext

func (e *ChannelEnumerator[T]) MoveNext() bool

MoveNext advances the enumerator to the next value in the range. Returns true if more values are available, false otherwise.

func (*ChannelEnumerator[T]) Publish

func (e *ChannelEnumerator[T]) Publish(msg T) bool

Publish sends a value to the enumerator for consumption.

type Disposable

type Disposable interface {
	Dispose()
}

type Enumerator

type Enumerator[T any] interface {
	Disposable
	MoveNext() bool
	Current() (T, error)
	Err() error
}

Enumerator represents a generic iterator over a sequence of values of type T. It should be disposed when no longer needed.

func Chain

func Chain[T any](enumerators ...Enumerator[T]) Enumerator[T]

func Chunk

func Chunk[T any, TSize constraints.Ordered](
	in Enumerator[T],
	target TSize,
	compute func(item T) (TSize, error),
) Enumerator[Enumerator[T]]

func ChunkByCount

func ChunkByCount[T any](in Enumerator[T], count int) Enumerator[Enumerator[T]]

func ChunkByKey

func ChunkByKey[T any, K comparable](
	in Enumerator[T],
	keyFunc func(T) K,
) Enumerator[Enumerator[KeyedItem[K, T]]]

func ChunkWhen

func ChunkWhen[V any, K comparable](
	in Enumerator[V],
	seed K,
	split func(prev K, item V) (K, bool, error),
) Enumerator[Enumerator[KeyedItem[K, V]]]

func Empty

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

Empty returns an enumerator that yields no elements.

func Error

func Error[T any](err error) Enumerator[T]

Error creates an enumerator that immediately returns an error.

func Filter

func Filter[T any](parent Enumerator[T], filter func(T) bool) Enumerator[T]

Filter creates a mapped enumerator

func FilterMap

func FilterMap[TIn any, TOut any](enumerator Enumerator[TIn], apply func(TIn) (TOut, bool, error)) Enumerator[TOut]

FilterMap creates a mapped enumerator

func FlatMap

func FlatMap[T any, U any](parent Enumerator[T], mapper func(T) Enumerator[U]) Enumerator[U]

FlatMap creates a flat-mapped enumerator

func Generate

func Generate[T any](next func() (T, bool, error)) Enumerator[T]

Generate gets a new enumerator using a generator func

func GenerateAndDispose

func GenerateAndDispose[T any](next func() (T, bool, error), dispose func()) Enumerator[T]

func GenerateFromMap

func GenerateFromMap[K comparable, V any](m map[K]V) Enumerator[*KeyValuePair[K, V]]

func Group

func Group[T any, G comparable](
	in Enumerator[T],
	compute func(item T) (G, error),
) Enumerator[*Grouping[T, G]]

func Interleave

func Interleave[T any, TOrdered constraints.Ordered](
	enumerators []Enumerator[T],
	key func(T) TOrdered,
) Enumerator[T]

Interleave creates a new interleave enumerator that merges multiple enumerators based on the ordering provided by the key function.

func Map

func Map[T any, U any](enumerator Enumerator[T], mapper func(T) (U, error)) Enumerator[U]

Map creates a mapped enumerator

func PageItemEnumerator

func PageItemEnumerator[T any](fetchPage func() ([]T, bool, error)) Enumerator[T]

func Range

func Range[T any](seed int, count int, factory func(i int) T) Enumerator[T]

func SkipIf

func SkipIf[T any](enumerator Enumerator[T], condition func(T) bool) Enumerator[T]

SkipIf skips the item if the contition is true

func Slice

func Slice[T any](slice []T) Enumerator[T]

func Take

func Take[T any](enumerator Enumerator[T], take int) Enumerator[T]

Take takes the specified number of items

func TakeWhile

func TakeWhile[T any](enumerator Enumerator[T], condition func(T) bool) Enumerator[T]

TakeWhile takes the item if the contition is true

type Generator

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

Generator generates values continuously.

func (*Generator[T]) Current

func (ce *Generator[T]) Current() (T, error)

Current returns the current value or an error if disposed.

func (*Generator[T]) Dispose

func (ce *Generator[T]) Dispose()

Dispose cleans up the enumerator.

func (*Generator[T]) Err

func (ce *Generator[T]) Err() error

Err returns the last error.

func (*Generator[T]) MoveNext

func (ce *Generator[T]) MoveNext() bool

MoveNext generates the next value.

type GroupEnumerator

type GroupEnumerator[T any, G comparable] struct {
	// contains filtered or unexported fields
}

func (*GroupEnumerator[T, G]) Current

func (e *GroupEnumerator[T, G]) Current() (*Grouping[T, G], error)

func (*GroupEnumerator[T, G]) Dispose

func (e *GroupEnumerator[T, G]) Dispose()

func (*GroupEnumerator[T, G]) Err

func (e *GroupEnumerator[T, G]) Err() error

func (*GroupEnumerator[T, G]) MoveNext

func (e *GroupEnumerator[T, G]) MoveNext() bool

type Grouping

type Grouping[T any, G comparable] struct {
	Enumerator *innerGroupEnumerator[T, G]
	Key        G
}

type GroupingSlice

type GroupingSlice[T any, G comparable] struct {
	Items []T
	Group G
}

func CollectGroupingSlices

func CollectGroupingSlices[T any, G comparable](enumerator Enumerator[*Grouping[T, G]]) (groupSlices []*GroupingSlice[T, G], err error)

CollectGroupingSlices gathers all chunks into a slice of slices

type KeyValuePair

type KeyValuePair[K comparable, V any] struct {
	Key   K
	Value V
}

type KeyedItem

type KeyedItem[K comparable, V any] struct {
	Key  K
	Item V
}

type PeekableEnumerator

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

PeekableEnumerator wraps an Enumerator and adds peek functionality

func Peekable

func Peekable[T any](inner Enumerator[T]) *PeekableEnumerator[T]

Peekable constructs a PeekableEnumerator

func (*PeekableEnumerator[T]) Current

func (p *PeekableEnumerator[T]) Current() (T, error)

Current returns the current element

func (*PeekableEnumerator[T]) Dispose

func (p *PeekableEnumerator[T]) Dispose()

Dispose releases resources

func (*PeekableEnumerator[T]) Err

func (p *PeekableEnumerator[T]) Err() error

Err returns the last error from the underlying enumerator

func (*PeekableEnumerator[T]) HasNext

func (p *PeekableEnumerator[T]) HasNext() bool

HasNext checks if there is a next element available without advancing the enumerator

func (*PeekableEnumerator[T]) MoveNext

func (p *PeekableEnumerator[T]) MoveNext() bool

MoveNext advances to the next element

func (*PeekableEnumerator[T]) Peek

func (p *PeekableEnumerator[T]) Peek() (T, bool, error)

Peek allows looking at the next element without advancing the enumerator

type SliceEnumerator

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

func (*SliceEnumerator[T]) Current

func (e *SliceEnumerator[T]) Current() (T, error)

func (*SliceEnumerator[T]) Dispose

func (enumerator *SliceEnumerator[T]) Dispose()

func (*SliceEnumerator[T]) Err

func (e *SliceEnumerator[T]) Err() error

func (*SliceEnumerator[T]) MoveNext

func (e *SliceEnumerator[T]) MoveNext() bool

Jump to

Keyboard shortcuts

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