x

package module
v4.3.0 Latest Latest
Warning

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

Go to latest
Published: May 2, 2024 License: MIT Imports: 17 Imported by: 0

README

x

A collection of functions to write concise code.

sha2 := sha256.New()
src := tar.NewReader(
	CloseAfterRead(Must(gzip.NewReader(
		io.TeeReader(
			CloseAfterRead(Must(http.Get("https://go.dev/dl/go1.20.2.linux-amd64.tar.gz")).Body),
			sha2,
		),
	))),
)
for th, err := src.Next(); err != io.EOF; th, err = src.Next() {
	Check(err)
	switch th.Typeflag {
	case tar.TypeDir:
		Check(os.Mkdir(th.Name, 0o755))
	case tar.TypeReg:
		dst := Must(os.OpenFile(th.Name, os.O_CREATE|os.O_WRONLY, th.FileInfo().Mode()))
		Must(io.Copy(dst, src))
		Check(dst.Close())
	}
}
Assert(hex.EncodeToString(sha2.Sum(nil)) == "4eaea32f59cde4dc635fbc42161031d13e1c780b87097f4b4234cfce671f1768")

This snippet downloads an archive, unpacks it and verifies its checksum, all in one go. Any error causes a panic, cascading errors are stacked and each reader is closed as expected.


If you get a warning from gopls/staticcheck about dot-import, create a file named staticcheck.conf in your project directory (or parents) with:

dot_import_whitelist = [ "github.com/xpetit/x/v4" ]

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AppendByte

func AppendByte[T Number](dst []byte, i T) []byte

AppendByte appends the string form of the byte count i, as generated by FormatByte, to dst and returns the extended buffer.

func AppendUnicodeBar

func AppendUnicodeBar(b []byte, width int) []byte

func Assert

func Assert(cond bool, a ...any)

Assert panics if cond is false.

func BarChart

func BarChart[M ~map[K]V, K cmp.Ordered, V Number](w io.Writer, m M, title string, maxItems int)

BarChart prints a bar chart with unicode block elements to help visualize m in a compact way. If maxItems > -1, it limits the amount of lines to display. Example with the number of online players for 8 games (data from steamcharts):

100%  2405676  Total (8 entries)
 50%  1195540  Counter-Strike: Global Offensive [██████      ]
 20%   473708  Dota 2                           [██▍         ]
 11%   275232  Apex Legends                     [█▍          ]
 10%   246234  PUBG: BATTLEGROUNDS              [█▎          ]
  5%   123765  Grand Theft Auto V               [▋           ]
  3%    64405  Team Fortress 2                  [▍           ]
  1%    21228  The Sims™ 4                      [▏           ]
  0%     5564  Sekiro™: Shadows Die Twice       [            ]

func Check

func Check(err error)

Check panics if its argument is a non-nil error. Examples:

Check(os.Chdir("directory"))

Check(json.NewDecoder(os.Stdin).Decode(&data))

func Clamp

func Clamp[T Number](val, min, max T) T

func CloseAfterRead

func CloseAfterRead(r io.ReadCloser) io.Reader

CloseAfterRead returns a Reader that automatically closes when there is no more data to read or an error has occurred. Examples:

// Prints SHA2 of "file_to_hash" in hexadecimal notation
h := sha256.New()
C2(io.Copy(h, CloseAfterRead(C2(os.Open("file_to_hash")))))
fmt.Println(hex.EncodeToString(h.Sum(nil)))

// Downloads a file
const url = "https://go.dev/dl/go1.20.2.linux-amd64.tar.gz"
dst := C2(os.Create(path.Base(url)))
defer Closing(dst)
C2(io.Copy(dst, CloseAfterRead(C2(http.Get(url)).Body)))

func Closing

func Closing(v io.Closer)

Closing is a shortcut, instead of writing:

defer func() { C(f.Close()) }()

One can write:

defer Closing(f)

func Filter

func Filter[S ~[]E, E any](s S, keep func(E) bool) S

Filter filters out in place elements of the slice

func FormatByte

func FormatByte[T Number](i T) string

func Goroutines

func Goroutines(nb int, fn func(i int)) (wait func())

Goroutines spawns nb goroutines executing fn. It returns a function that waits for them to finish.

func Has

func Has[M ~map[K]V, K comparable, V any](m M, k K) bool

Has returns whether k is present in the map m.

func InitUnicodeCategory

func InitUnicodeCategory()

InitUnicodeCategory inits the cache for UnicodeCategory It is exported so that the user can trigger cache building instead of waiting for the first call to UnicodeCategory.

func Intn

func Intn[T Integer](n T) T

Intn returns a uniform random value in [0, n). It panics if n <= 0.

func Keys

func Keys[M ~map[K]V, K comparable, V any](m M) []K

Keys returns the keys of the map m. The keys will be in an indeterminate order.

func MultiLines

func MultiLines(s string) string

MultiLines formats a multiline raw string, changing:

`
	First line
		Second line
		Third line
`

to:

`First line
	Second line
	Third line`

It is intended to be called like this:

MultiLines(`
	First Line
		Second line
		Third line
`)

func Must

func Must[T any](a T, err error) T

Must panics if its second argument is a non-nil error and returns the first one. Examples:

i := Must(strconv.Atoi("123"))

f := Must(os.Open("file"))

func Must2

func Must2[T1, T2 any](a T1, b T2, err error) (T1, T2)

Must2 panics if its third argument is a non-nil error and returns the first two. Examples:

img, _ := Must2(image.Decode(f))

_, port := Must2(net.SplitHostPort(address))

func One

func One[M ~map[K]V, K comparable, V any](m M) (K, V)

One returns a key and value from a map, which must not be empty.

func Output

func Output(c *exec.Cmd) ([]byte, error)

Output is similar to (*exec.Cmd).Output() but conveniently wraps exec.ExitError with stderr:

_, err1 := exec.Command("ls", "").Output() // standard way
_, err2 := Output(exec.Command("ls", ""))  // with this function

err1.Error() == "exit status 2"
err2.Error() == "exit status 2: ls: cannot access '': No such file or directory"

The underlying *exec.ExitError remains recoverable:

if err := new(exec.ExitError); errors.As(err2, &err) {
	fmt.Println(err.UserTime())
}

func Ptr

func Ptr[T any](v T) *T

Ptr returns a pointer to v.

func Run

func Run(c *exec.Cmd) error

Run is similar to (*exec.Cmd).Run() but conveniently wraps exec.ExitError with stderr:

err1 := exec.Command("go", "run").Run() // standard way
err2 := Run(exec.Command("go", "run"))  // with this function

err1.Error() == "exit status 1"
err2.Error() == "exit status 1: go: no go files listed"

The underlying *exec.ExitError remains recoverable:

if err := new(exec.ExitError); errors.As(err2, &err) {
	fmt.Println(err.UserTime())
}

func Set

func Set[M ~map[K]V, K comparable, V any](m M, k K, v V) bool

func Shuffle

func Shuffle[S ~[]E, E any](s S)

Shuffle shuffles a slice randomly.

func Sort

func Sort[S ~[]E, E cmp.Ordered](x S) S

func StdinIsPipe

func StdinIsPipe() bool

func StdoutIsTerminal

func StdoutIsTerminal() bool

func ToSet

func ToSet[S ~[]E, E comparable](s S) map[E]struct{}

func UnicodeBar

func UnicodeBar(width int) string

func UnicodeCategory

func UnicodeCategory(r rune) (name string)

UnicodeCategory returns the code point General Category. It is a two bytes string with major & minor e.g. "Lu", "Zs", "Nd"...

func Values

func Values[M ~map[K]V, K comparable, V any](m M) []V

Values returns the values of the map m. The values will be in an indeterminate order.

Types

type Float

type Float interface {
	~float32 | ~float64
}

type Integer

type Integer interface {
	~uint8 | ~uint16 | ~uint32 | ~uint64 |
		~int8 | ~int16 | ~int32 | ~int64 |
		int | ~uint | ~uintptr
}

type Number

type Number interface {
	Integer | Float
}

type Protected added in v4.2.0

type Protected[K comparable, V any] struct {
	M    map[K]V
	Lock sync.RWMutex
	// contains filtered or unexported fields
}

func (*Protected[K, _]) Delete added in v4.2.0

func (p *Protected[K, _]) Delete(k K)

func (*Protected[K, V]) Do added in v4.3.0

func (p *Protected[K, V]) Do(fn func(map[K]V))

func (*Protected[K, V]) Get added in v4.2.0

func (p *Protected[K, V]) Get(k K) (v V, ok bool)

func (*Protected[K, _]) Has added in v4.2.0

func (p *Protected[K, _]) Has(k K) bool

func (*Protected[K, V]) Set added in v4.2.0

func (p *Protected[K, V]) Set(k K, v V)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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