mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-06-12 17:27:52 +02:00
07c8adaf76
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
171 lines
3.8 KiB
Go
171 lines
3.8 KiB
Go
package iter
|
|
|
|
import (
|
|
"context"
|
|
"iter"
|
|
)
|
|
|
|
// Pull converts a push-style iterator (Seq) to a pull-style iterator.
|
|
// Returns a next function that yields the next value and a boolean indicating if valid,
|
|
// and a stop function that should be called to release resources.
|
|
//
|
|
// Example:
|
|
//
|
|
// next, stop := iter.Pull(iter.FromSlice([]int{1, 2, 3}))
|
|
// defer stop()
|
|
// for {
|
|
// v, ok := next()
|
|
// if !ok { break }
|
|
// fmt.Println(v)
|
|
// }
|
|
func Pull[T any](s Seq[T]) (next func() (T, bool), stop func()) {
|
|
return iter.Pull(iter.Seq[T](s))
|
|
}
|
|
|
|
// Pull2 converts a push-style iterator (Seq2) to a pull-style iterator.
|
|
func Pull2[K, V any](s Seq2[K, V]) (next func() (K, V, bool), stop func()) {
|
|
return iter.Pull2(iter.Seq2[K, V](s))
|
|
}
|
|
|
|
// Context wraps a sequence with context cancellation.
|
|
// If the context is cancelled, iteration stops early.
|
|
//
|
|
// Example:
|
|
//
|
|
// ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
// defer cancel()
|
|
// s := iter.Context(iter.FromSlice([]int{1, 2, 3}), ctx)
|
|
func Context[T any](s Seq[T], ctx context.Context) Seq[T] {
|
|
return func(yield func(T) bool) {
|
|
if err := ctx.Err(); err != nil {
|
|
return
|
|
}
|
|
s(func(v T) bool {
|
|
select {
|
|
case <-ctx.Done():
|
|
return false
|
|
default:
|
|
return yield(v)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Context2 wraps a key-value sequence with context cancellation.
|
|
// If the context is cancelled, iteration stops early.
|
|
//
|
|
// Example:
|
|
//
|
|
// ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
// defer cancel()
|
|
// s := iter.Context2(iter.FromMap(map[int]string{1: "a", 2: "b"}), ctx)
|
|
func Context2[K, V any](s Seq2[K, V], ctx context.Context) Seq2[K, V] {
|
|
return func(yield func(K, V) bool) {
|
|
if err := ctx.Err(); err != nil {
|
|
return
|
|
}
|
|
s(func(k K, v V) bool {
|
|
select {
|
|
case <-ctx.Done():
|
|
return false
|
|
default:
|
|
return yield(k, v)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// ToChan converts a sequence to a channel.
|
|
// The channel is closed when the sequence is exhausted or context is cancelled.
|
|
//
|
|
// Example:
|
|
//
|
|
// ctx := context.Background()
|
|
// ch := iter.ToChan(iter.FromSlice([]int{1, 2, 3}), ctx)
|
|
// for v := range ch {
|
|
// fmt.Println(v)
|
|
// }
|
|
func ToChan[T any](s Seq[T], ctx context.Context) chan T {
|
|
ch := make(chan T)
|
|
go func() {
|
|
defer close(ch)
|
|
if err := ctx.Err(); err != nil {
|
|
return
|
|
}
|
|
s(func(v T) bool {
|
|
select {
|
|
case <-ctx.Done():
|
|
return false
|
|
case ch <- v:
|
|
return true
|
|
}
|
|
})
|
|
}()
|
|
return ch
|
|
}
|
|
|
|
// ToChan2 converts a key-value sequence to a channel of Pair pairs.
|
|
// The channel is closed when the sequence is exhausted or context is cancelled.
|
|
//
|
|
// Example:
|
|
//
|
|
// ctx := context.Background()
|
|
// ch := iter.ToChan2(iter.FromMap(map[int]string{1: "a", 2: "b"}), ctx)
|
|
// for kv := range ch {
|
|
// fmt.Printf("%d: %s\n", kv.K, kv.V)
|
|
// }
|
|
func ToChan2[K, V any](s Seq2[K, V], ctx context.Context) chan Pair[K, V] {
|
|
ch := make(chan Pair[K, V])
|
|
go func() {
|
|
defer close(ch)
|
|
if err := ctx.Err(); err != nil {
|
|
return
|
|
}
|
|
s(func(k K, v V) bool {
|
|
select {
|
|
case <-ctx.Done():
|
|
return false
|
|
case ch <- Pair[K, V]{k, v}:
|
|
return true
|
|
}
|
|
})
|
|
}()
|
|
return ch
|
|
}
|
|
|
|
// ToSlice collects all elements from the sequence into a slice.
|
|
//
|
|
// Example:
|
|
//
|
|
// s := iter.FromSlice([]int{1, 2, 3})
|
|
// sl := iter.ToSlice(s) // [1, 2, 3]
|
|
func ToSlice[T any](s Seq[T]) []T {
|
|
out := make([]T, 0)
|
|
s(func(v T) bool {
|
|
out = append(out, v)
|
|
return true
|
|
})
|
|
return out
|
|
}
|
|
|
|
// ToMap collects all key-value pairs into a map.
|
|
// Later pairs with the same key will overwrite earlier ones.
|
|
func ToMap[K comparable, V any](s Seq2[K, V]) map[K]V {
|
|
m := make(map[K]V)
|
|
s(func(k K, v V) bool {
|
|
m[k] = v
|
|
return true
|
|
})
|
|
return m
|
|
}
|
|
|
|
// ToPairs collects all key-value pairs into a slice of Pair structs.
|
|
func ToPairs[K, V any](s Seq2[K, V]) []Pair[K, V] {
|
|
out := make([]Pair[K, V], 0)
|
|
s(func(k K, v V) bool {
|
|
out = append(out, Pair[K, V]{k, v})
|
|
return true
|
|
})
|
|
return out
|
|
}
|