goext

package module
v0.4.4 Latest Latest
Warning

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

Go to latest
Published: Nov 12, 2023 License: MIT Imports: 6 Imported by: 13

README

GoExt

Extended functionalities that are missing in the Go standard library but frequently used in other languages.

Especially for JavaScript developers, these packages should make us feel right at home.

Install

go get github.com/ayonli/goext

Functions

goext.ReadAll
func ReadAll[T any](ch <-chan T) []T

ReadAll reads all values from the channel at once.


goext.Ok
func Ok[R any](res R, err error) R

Ok asserts a typical Golang function call which returns a result and an error is successful and returns the result, it panics if the return error is not nil. This function should be composite with the goext.Try() function, allowing the program to bubble the error and catch it from outside.

Example

_, err := goext.Try(func () int {
    res1 := goext.Ok(someCall())
    res2 := goext.Ok(anotherCall())
    return 0
})

goext.Try
func Try[R any](fn func() R) (res R, err error)

Try runs a function in a safe context where if it or what's inside it panics, the panic reason can be caught and returned as a normal error.

Example

_, err := goext.Try(func () int {
    res1 := goext.Ok(someCall())
    res2 := goext.Ok(anotherCall())
    return 0
})

goext.Queue
func Queue[T any](handler func(data T), bufferSize int) IQueue[T]

Queue processes data sequentially by the given handler function and prevents concurrency conflicts, it returns a queue instance that we can push data into.

bufferSize is the maximum capacity of the underlying channel, once reached, the push operation will block until there is new space available. Bu default, this option is not set and use a non-buffered channel instead.


goext.Throttle
func Throttle[A any, R any, Fn func(arg A) (R, error)](
    handler Fn,
    duration time.Duration,
    forKey string,
    noWait bool,
) Fn

Creates a throttled function that will only be run once in a certain amount of time.

If a subsequent call happens within the duration, the previous result will be returned and the handler function will not be invoked.

If forKey is provided, use the throttle strategy for the given key, this will keep the result in a global cache, binding new handler function for the same key will result in the same result as the previous, unless the duration has passed. This mechanism guarantees that both creating the throttled function in function scopes and overwriting the handler are possible.

If noWait is turned on, respond with the last cache (if available) immediately, even if it has expired, and update the cache in the background.

Sub-packages

  • async (Since v0.2.0) Package async provides functions to run functions in other goroutines and wait for their results.
  • mathx Additional functions for math calculation that are missing in the standard library.
  • stringx Additional functions for string processing that are missing in the standard library.
    • mbstring Additional functions for processing strings in multi-byte sequence.
  • slicex Additional functions for playing with slices and reduce mistakes.
  • mapx Additional functions for dealing with maps.
  • structx (Since v0.3.0) Functions used to manipulate structs.
  • number (Since v0.4.0) Functions for dealing with numbers.
  • oop Object-oriented abstract wrappers for basic data structures.
    • String is an object-oriented abstract that works around multi-byte strings.
    • List is an objected-oriented abstract that works around the slice and acts as a dynamic array.
  • collections Object-oriented abstract wrappers for basic types.
    • Set is an object-oriented collection that stores unique items and is thread-safe.
    • Map is an object-oriented collection of map with ordered keys and thread-safe by default.
    • CiMap Thread-safe case-insensitive map, keys are case-insensitive.
    • BiMap Thread-safe bi-directional map, keys and values are unique and map to each other.

Documentation

Overview

Please check each package / sub-directory for their details.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Ok added in v0.3.1

func Ok[R any](res R, err error) R

Ok asserts a typical Golang function call which returns a result and an error is successful and returns the result, it panics if the return error is not nil. This function should be composite with the `goext.Try()` function, allowing the program to bubble the error and catch it from outside.

Example:

_, err := goext.Try(func () int {
	res1 := goext.Ok(someCall())
	res2 := goext.Ok(anotherCall())
	return 0
})
Example
package main

import (
	"errors"
	"fmt"

	"github.com/ayonli/goext"
)

func main() {
	texture := func(good bool) (string, error) {
		if !good {
			return "", errors.New("something went wrong")
		}

		return "everything looks fine", nil
	}

	res, err := goext.Try(func() string {
		text := goext.Ok(texture(true))
		return text
	})

	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(res)
	}
}
Output:

everything looks fine
Example (Error)
package main

import (
	"errors"
	"fmt"

	"github.com/ayonli/goext"
)

func main() {
	texture := func(good bool) (string, error) {
		if !good {
			return "", errors.New("something went wrong")
		}

		return "everything looks fine", nil
	}

	res, err := goext.Try(func() string {
		text := goext.Ok(texture(false))
		return text
	})

	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(res)
	}
}
Output:

something went wrong

func ReadAll added in v0.4.0

func ReadAll[T any](ch <-chan T) []T

ReadAll reads all values from the channel at once.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext"
)

func main() {
	ch := make(chan int, 3)

	ch <- 1
	ch <- 2
	ch <- 3
	close(ch)

	fmt.Println(goext.ReadAll(ch))
}
Output:

[1 2 3]

func Throttle added in v0.4.0

func Throttle[A any, R any, Fn func(arg A) (R, error)](
	handler Fn,
	duration time.Duration,
	forKey string,
	noWait bool,
) Fn

Creates a throttled function that will only be run once in a certain amount of time.

If a subsequent call happens within the `duration`, the previous result will be returned and the `handler` function will not be invoked.

If `forKey` is provided, use the throttle strategy for the given key, this will keep the result in a global cache, binding new `handler` function for the same key will result in the same result as the previous, unless the duration has passed. This mechanism guarantees that both creating the throttled function in function scopes and overwriting the handler are possible.

If `noWait` is turned on, respond with the last cache (if available) immediately, even if it has expired, and update the cache in the background.

Example (WithKey)
package main

import (
	"fmt"
	"time"

	"github.com/ayonli/goext"
)

func main() {
	res1, err1 := goext.Throttle[int](func(arg int) (int, error) {
		return arg * 2, nil
	}, time.Millisecond*5, "foo", false)(1)
	res2, err2 := goext.Throttle[int](func(arg int) (int, error) {
		return arg * 2, nil
	}, time.Millisecond*5, "foo", false)(2)

	fmt.Println(res1, err1)
	fmt.Println(res2, err2)

	time.Sleep(time.Millisecond * 6)
	res3, err3 := goext.Throttle[int](func(arg int) (int, error) {
		return arg * 2, nil
	}, time.Millisecond*5, "foo", false)(3)
	fmt.Println(res3, err3)

}
Output:

2 <nil>
2 <nil>
6 <nil>
Example (WithoutKey)
package main

import (
	"fmt"
	"time"

	"github.com/ayonli/goext"
)

func main() {
	fn := goext.Throttle[int](func(arg int) (int, error) {
		return arg * 2, nil
	}, time.Millisecond*5, "", false)

	fmt.Println(fn(1))
	fmt.Println(fn(2))

	time.Sleep(time.Millisecond * 6)
	fmt.Println(fn(3))

}
Output:

2 <nil>
2 <nil>
6 <nil>

func Try

func Try[R any](fn func() R) (res R, err error)

Try runs a function in a safe context where if it or what's inside it panics, the panic reason can be caught and returned as a normal error.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext"
)

func main() {
	texture := func(good bool) string {
		if !good {
			panic("something went wrong")
		}

		return "everything looks fine"
	}

	res, err := goext.Try(func() string {
		text := texture(true)
		return text
	})

	fmt.Println(res)
	fmt.Println(err)
}
Output:

everything looks fine
<nil>
Example (PanicAny)
package main

import (
	"fmt"

	"github.com/ayonli/goext"
)

func main() {
	texture := func(good bool) string {
		if !good {
			panic(1)
		}

		return "everything looks fine"
	}

	res, err := goext.Try(func() string {
		text := texture(false)
		return text
	})

	fmt.Printf("%#v\n", res)
	fmt.Println(err)
}
Output:

""
1
Example (PanicError)
package main

import (
	"errors"
	"fmt"

	"github.com/ayonli/goext"
)

func main() {
	texture := func(good bool) string {
		if !good {
			panic(errors.New("something went wrong"))
		}

		return "everything looks fine"
	}

	res, err := goext.Try(func() string {
		text := texture(false)
		return text
	})

	fmt.Printf("%#v\n", res)
	fmt.Println(err)
}
Output:

""
something went wrong
Example (PanicString)
package main

import (
	"fmt"

	"github.com/ayonli/goext"
)

func main() {
	texture := func(good bool) string {
		if !good {
			panic("something went wrong")
		}

		return "everything looks fine"
	}

	res, err := goext.Try(func() string {
		text := texture(false)
		return text
	})

	fmt.Printf("%#v\n", res)
	fmt.Println(err)
}
Output:

""
something went wrong

func Wrap deprecated added in v0.3.1

func Wrap[R any](fn func(args ...any) R) func(args ...any) (R, error)

Wrap returns a new function that wraps the `goext.Try()`, rendering the new function already catchable.

Deprecated: this function is not good.

Types

type IQueue added in v0.4.0

type IQueue[T any] interface {
	Push(data T)
	Close()
	OnError(handler func(err error))
}

func Queue added in v0.4.0

func Queue[T any](handler func(data T), bufferSize int) IQueue[T]

Queue processes data sequentially by the given `handler` function and prevents concurrency conflicts, it returns a queue instance that we can push data into.

`bufferSize` is the maximum capacity of the underlying channel, once reached, the push operation will block until there is new space available. Bu default, this option is not set and use a non-buffered channel instead.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext"
)

func main() {
	out := make(chan []string)
	list := []string{}
	queue := goext.Queue(func(str string) {
		list = append(list, str)

		if len(list) == 2 {
			out <- list
		}
	}, 0)

	go func() {
		queue.Push("foo")
	}()

	go func() {
		queue.Push("bar")
	}()

	fmt.Println(len(<-out))
	queue.Close()
}
Output:

2
Example (Error)
package main

import (
	"errors"
	"fmt"

	"github.com/ayonli/goext"
)

func main() {
	out := make(chan error)
	queue := goext.Queue(func(str string) {
		if str == "error" {
			panic(errors.New("something went wrong"))
		}
	}, 0)

	queue.OnError(func(err error) {
		out <- err
	})

	queue.Push("error")

	err := <-out
	fmt.Println(err)
}
Output:

something went wrong

type QueueImpl added in v0.4.0

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

func (*QueueImpl[T]) Close added in v0.4.0

func (queue *QueueImpl[T]) Close()

func (*QueueImpl[T]) OnError added in v0.4.0

func (queue *QueueImpl[T]) OnError(handler func(err error))

func (*QueueImpl[T]) Push added in v0.4.0

func (queue *QueueImpl[T]) Push(data T)

Directories

Path Synopsis
Package async provides functions to run functions in other goroutines and wait for their results.
Package async provides functions to run functions in other goroutines and wait for their results.
Collection objects such as **Map**, **Set**, etc.
Collection objects such as **Map**, **Set**, etc.
Additional functions for dealing with maps.
Additional functions for dealing with maps.
Additional functions for math calculation that are missing in the standard library.
Additional functions for math calculation that are missing in the standard library.
Functions for dealing with numbers.
Functions for dealing with numbers.
Object-oriented abstract wrappers for basic types.
Object-oriented abstract wrappers for basic types.
Additional functions for playing with slices and reduce mistakes.
Additional functions for playing with slices and reduce mistakes.
Additional functions for string processing that are missing in the standard library.
Additional functions for string processing that are missing in the standard library.
mbstring
Additional functions for processing strings in multi-byte sequence.
Additional functions for processing strings in multi-byte sequence.
Functions used to manipulate structs.
Functions used to manipulate structs.

Jump to

Keyboard shortcuts

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