Last active
March 31, 2021 14:53
-
-
Save ninedraft/022f0978065a4174a33a7483a0c16794 to your computer and use it in GitHub Desktop.
Go2 std
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func Await[C context.Context, E any](ctx C, ch <-chan E) (E, bool) { | |
select { | |
case <-ctx.Done(): | |
var empty E | |
return empty, false | |
case v, ok := <-ch: | |
return v, ok | |
} | |
} | |
type BatchFormer[T any] struct { | |
maxSize uint | |
buf []T | |
consumer func([]T) error | |
} | |
func NewBatchFormer[T any](max uint, consumer func([]T) error) *BatchFormer[T] { | |
if consumer == nil { | |
panic("BatchFormer: consumer must be not nil") | |
} | |
return &BatchFormer[T]{ | |
maxSize: max, | |
buf: make([]T, 0, max), | |
consumer: consumer, | |
} | |
} | |
func (bf *BatchFormer[T]) Push(v T) error { | |
bf.buf = append(bf.buf, v) | |
if uint(len(bf.buf)) < bf.maxSize { | |
return nil | |
} | |
return bf.Flush() | |
} | |
func (bf *BatchFormer[T]) Seep(ctx context.Context, ch <-chan T) error { | |
for { | |
var v, ok = Await(ctx, ch) | |
if !ok { | |
return nil | |
} | |
var err = bf.Push(v) | |
if err != nil { | |
return err | |
} | |
} | |
} | |
func (bf *BatchFormer[T]) Flush() error { | |
defer bf.reset() | |
if len(bf.buf) == 0 { | |
return nil | |
} | |
return bf.consumer(bf.buf) | |
} | |
func (bf *BatchFormer[T]) reset() { | |
var void T | |
for i := range bf.buf { | |
bf.buf[i] = void | |
} | |
bf.buf = bf.buf[:0] | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Task[T any] func(ctx context.Context, x T) error | |
func Distribute[T any](ctx context.Context, x T, tasks ...Task[T]) error { | |
var wg = &sync.WaitGroup{} | |
wg.Add(len(tasks)) | |
ctx, cancel := context.WithCancel(ctx) | |
defer cancel() | |
var joiner = &errorJoiner{} | |
for _, task := range tasks { | |
task := task | |
go func() { | |
defer wg.Done() | |
joiner.Push(task(ctx, x)) | |
}() | |
} | |
wg.Wait() | |
return nil | |
} | |
type errorJoiner struct { | |
mu sync.Mutex | |
err error | |
} | |
func (ej *errorJoiner) Push(err error) { | |
if err == nil { | |
return | |
} | |
ej.mu.Lock() | |
defer ej.mu.Unlock() | |
ej.err = err | |
} | |
func (ej *errorJoiner) Err() error { | |
ej.mu.Lock() | |
defer ej.mu.Unlock() | |
return ej.err | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type HashSet[E comparable] map[E]struct{} | |
func From[E comparable](items ...E) HashSet[E] { | |
var set = make(HashSet[E], len(items)) | |
for _, item := range items { | |
set[item] = struct{}{} | |
} | |
return set | |
} | |
func FromItems[E comparable](items []E) HashSet[E] { | |
var set = make(HashSet[E], len(items)) | |
for _, item := range items { | |
set[item] = struct{}{} | |
} | |
return set | |
} | |
func FromIter[E comparable](n int, next func(i int) (E, bool)) HashSet[E] { | |
var preallocate = n | |
if preallocate <= 0 { | |
preallocate = 16 | |
} | |
var set = make(HashSet[E], preallocate) | |
for i := 0; i < n || n < 0; i++ { | |
var item, ok = next(i) | |
if !ok { | |
break | |
} | |
set[item] = struct{}{} | |
} | |
return set | |
} | |
func (set HashSet[E]) Len() int { return len(set) } | |
func (set HashSet[E]) Add(item E) { | |
set[item] = struct{}{} | |
} | |
func (set HashSet[E]) AddItems(items []E) { | |
for _, item := range items { | |
set.Add(item) | |
} | |
} | |
func (set HashSet[E]) Contains(item E) bool { | |
var _, ok = set[item] | |
return ok | |
} | |
func (set HashSet[E]) Delete(item E) bool { | |
if set.Contains(item) { | |
delete(set, item) | |
return true | |
} | |
return false | |
} | |
func (set HashSet[E]) Clone() HashSet[E] { | |
var c = make(HashSet[E], set.Len()) | |
for item := range set { | |
c.Add(item) | |
} | |
return c | |
} | |
func (set HashSet[E]) Items() []E { | |
var items = make([]E, 0, set.Len()) | |
for item := range set { | |
items = append(items, item) | |
} | |
return items | |
} | |
func (set HashSet[E]) Equal(other HashSet[E]) bool { | |
if set.Len() != other.Len() { | |
return false | |
} | |
for item := range set { | |
if !other.Contains(item) { | |
return false | |
} | |
} | |
return true | |
} | |
func (set HashSet[E]) Intersect(other HashSet[E]) { | |
for item := range set { | |
if !other.Contains(item) { | |
delete(set, item) | |
} | |
} | |
} | |
func (set HashSet[E]) Sub(other HashSet[E]) { | |
for item := range other { | |
delete(set, item) | |
} | |
} | |
func (set HashSet[E]) SubItems(items []E) { | |
for _, item := range items { | |
delete(set, item) | |
} | |
} | |
func (set HashSet[E]) Filter(predicate func(E) bool) HashSet[E] { | |
var n int | |
for item := range set { | |
if predicate(item) { | |
n++ | |
} | |
} | |
var result = make(HashSet[E], n) | |
for item := range set { | |
if predicate(item) { | |
result[item] = struct{}{} | |
} | |
} | |
return result | |
} | |
func (set HashSet[E]) Count(predicate func(E) bool) int { | |
var n int | |
for item := range set { | |
if predicate(item) { | |
n++ | |
} | |
} | |
return n | |
} | |
func (set HashSet[E]) Reset() { | |
for item := range set { | |
delete(set, item) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Map[K comparable, V any] map[K]V | |
func (m Map[K, V]) Len() int { return len(m) } | |
func (m Map[K, V]) Rename(from, to K) bool { | |
var v, ok = m[from] | |
if !ok { | |
return ok | |
} | |
delete(m, from) | |
m[to] = v | |
return true | |
} | |
func (m Map[K, V]) GetOr(key K, or V) V { | |
var v, ok = m[key] | |
if !ok { | |
return or | |
} | |
return v | |
} | |
return true | |
} | |
func (m Map[K, V]) Pop(key K) (_ V, ok bool) { | |
var v, exists = m[key] | |
if !exists { | |
return v, exists | |
} | |
delete(m, key) | |
return v, true | |
} | |
func (m Map[K, V]) GetOr(key K, or V) V { | |
var v, ok = m[key] | |
if !ok { | |
return or | |
} | |
return v | |
} | |
func (m Map[K, V]) GetOrFn(key K, or func() V) V { | |
var v, ok = m[key] | |
if !ok { | |
return or() | |
} | |
return v | |
} | |
func (m Map[K, V]) Keys() []K { | |
var keys = make([]K, 0, len(m)) | |
for k := range m { | |
keys = append(keys, k) | |
} | |
return keys | |
} | |
func (m Map[K, V]) Values() []V { | |
var values = make([]V, 0, len(m)) | |
for _, v := range m { | |
values = append(values, v) | |
} | |
return values | |
} | |
type KV[K comparable, V any] struct { | |
Key K | |
Value V | |
} | |
func (m Map[K, V]) Pairs() []KV[K, V] { | |
var kvs = make([]KV[K, V], 0, len(m)) | |
for k, v := range m { | |
kvs = append(kvs, KV[K, V]{ | |
Key: k, | |
Value: v, | |
}) | |
} | |
return kvs | |
} | |
func (m Map[K, V]) Select(keys ...K) []V { | |
var values = make([]V, 0, len(keys)) | |
for _, k := range keys { | |
var v, ok = m[k] | |
if ok { | |
values = append(values, v) | |
} | |
} | |
return values | |
} | |
func (m Map[K, V]) Delete(keys ...K) int { | |
var i int | |
for _, key := range keys { | |
delete(m, key) | |
i++ | |
} | |
return i | |
} | |
func (m Map[K, V]) Contains(key K) bool { | |
var _, ok = m[key] | |
return ok | |
} | |
func (m Map[K, V]) Reset() { | |
for key := range m { | |
delete(m, key) | |
} | |
} | |
func (m Map[K, V]) Clone() Map[K, V] { | |
var cp = make(Map[K, V], m.Len()) | |
for k, v := range m { | |
cp[k] = v | |
} | |
return cp | |
} | |
func (m Map[K, V]) Merge(other map[K]V) { | |
for k, v := range other { | |
m[k] = v | |
} | |
} | |
func (m Map[K, V]) MergeWithColl(other map[K]V, collate func(K, V, V) V) { | |
for k, v := range other { | |
m[k] = collate(k, m[k], v) | |
} | |
} | |
func (m Map[K, V]) Take(keys ...K) Map[K, V] { | |
var subset = make(Map[K, V], len(keys)) | |
for _, key := range keys { | |
var value, ok = m[key] | |
if ok { | |
subset[key] = value | |
} | |
} | |
return subset | |
} | |
func In[K, V comparable](a, b Map[K, V]) bool { | |
for k, v := range a { | |
if v != b[k] { | |
return false | |
} | |
} | |
return true | |
} | |
func InWithEq[K comparable, V any](a, b Map[K, V], eq func(V, V) bool) bool { | |
for k, v := range a { | |
if !eq(v, b[k]) { | |
return false | |
} | |
} | |
return true | |
} | |
func IsEqual[K, V comparable](a, b Map[K, V]) bool { | |
if len(a) != len(b) { | |
return false | |
} | |
return In(a, b) | |
} | |
func IsEqualWithEq[K comparable, V any](a, b Map[K, V], eq func(V, V) bool) bool { | |
if len(a) != len(b) { | |
return false | |
} | |
return InWithEq(a, b, eq) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package option | |
type Opt[E any] struct { | |
v E | |
} | |
func (opt *Opt[E]) Unwrap() E { | |
if opt.HasValue() { | |
return opt.v | |
} | |
panic("unwrapping Opt: got empty optional value") | |
} | |
func (opt *Opt[E]) HasValue() bool { | |
return opt != nil | |
} | |
func (opt *Opt[E]) Unpack() (_ E, ok bool) { | |
if opt.HasValue() { | |
return opt.v, true | |
} | |
return empty[E](), false | |
} | |
func (opt *Opt[E]) Slice() []E { | |
if opt.HasValue() { | |
return []E{opt.v} | |
} | |
return nil | |
} | |
func (opt *Opt[E]) Then(fn func(v E)) { | |
if opt.HasValue() { | |
fn(opt.v) | |
} | |
} | |
func (opt *Opt[E]) UnwrapOrEmpty() E { | |
if opt.HasValue() { | |
return opt.v | |
} | |
return empty[E]() | |
} | |
func (opt *Opt[E]) UnwrapOr(or E) E { | |
if opt.HasValue() { | |
return opt.v | |
} | |
return or | |
} | |
func Some[E any](v E) *Opt[E] { | |
return &Opt[E]{ | |
v: v, | |
} | |
} | |
func SomePtr[E any](ptr *E) *Opt[E] { | |
if ptr == nil { | |
return None[E]() | |
} | |
return Some[E](*ptr) | |
} | |
func None[E any]() *Opt[E] { | |
return nil | |
} | |
func empty[E any]() E { | |
var v E | |
return v | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package result | |
func Ok[V any](v V) Result[V] { | |
return Result[V]{Value: v} | |
} | |
func Error[V any](err error) Result[V] { | |
return Result[V]{Error: err} | |
} | |
func Wrap[V any](v V, err error) Result[V] { | |
if err != nil { | |
return Error[V](err) | |
} | |
return Ok[V](v) | |
} | |
type Result[V any] struct { | |
Error error | |
Value V | |
} | |
func (result Result[V]) Unwrap() V { | |
if result.Error == nil { | |
return result.Value | |
} | |
var v V | |
var msg = "Result[" + reflect.TypeOf(v).String() + "]: unwrapping empty" | |
panic(msg) | |
} | |
func (result Result[V]) UnwrapOr(or V) V { | |
if result.Error == nil { | |
return result.Value | |
} | |
return or | |
} | |
func (result Result[V]) Ok() bool { return result.Error == nil } | |
func (result Result[V]) Slice() []V { | |
if result.Error == nil { | |
return []V{result.Value} | |
} | |
return nil | |
} | |
func (result Result[V]) With(f func(V) error) Result[V] { | |
if result.Error != nil { | |
return result | |
} | |
var err = f(result.Value) | |
if err != nil { | |
return Error[V](err) | |
} | |
return result | |
} | |
func (result Result[V]) WithValue(v V) Result[V] { | |
if result.Error != nil { | |
return Ok[V](v) | |
} | |
return result | |
} | |
func (result Result[V]) WithError(err error) Result[V] { | |
if result.Error != nil { | |
return result | |
} | |
return Error[V](err) | |
} | |
func (result Result[V]) Unpack() (V, error) { | |
return result.Value, result.Error | |
} | |
type Mapper[F, T any] func(F) (T, error) | |
func Map[F, T any](r Result[F], f Mapper[F, T]) Result[T] { | |
if !r.Ok() { | |
return Error[T](r.Error) | |
} | |
var v, err = f(r.Value) | |
if err != nil { | |
return Error[T](err) | |
} | |
return Ok[T](v) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment