x

package module
v2.0.5 Latest Latest
Warning

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

Go to latest
Published: Aug 4, 2023 License: MIT Imports: 18 Imported by: 10

README

X

A collection of functions to write concise code.

sha2 := sha256.New()
src := tar.NewReader(
	CloseAfterRead(C2(gzip.NewReader(
		io.TeeReader(
			CloseAfterRead(C2(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() {
	C(err)
	switch th.Typeflag {
	case tar.TypeDir:
		C(os.Mkdir(th.Name, 0o755))
	case tar.TypeReg:
		dst := C2(os.OpenFile(th.Name, os.O_CREATE|os.O_WRONLY, th.FileInfo().Mode()))
		C2(io.Copy(dst, src))
		C(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/v2" ]

Other useful generic functions can be found at:

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AppendByte added in v2.0.1

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 added in v2.0.3

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

func Assert

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

Assert panics if cond is false.

func BarChart added in v2.0.4

func BarChart[M ~map[K]V, K comparable, V constraints.Integer](w io.Writer, m M, 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 C

func C(err error)

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

C(os.Chdir("directory"))

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

func C2

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

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

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

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

func C3

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

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

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

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

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 FormatByte added in v2.0.1

func FormatByte[T Number](i T) string

func Goroutines added in v2.0.1

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

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

func HasKey

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

HasKey returns whether k is present in the map m.

func InitUnicodeCategory added in v2.0.4

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 constraints.Integer](n T) T

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

func IsNaN32 added in v2.0.4

func IsNaN32(f float32) bool

IsNaN32 is the float32 variant of math.IsNaN.

func Less added in v2.0.4

func Less[T comparable](a, b T) bool

Less implements "<" for some core types

func Max

func Max[T Number](x, y T) T

Max returns the larger of x or y.

func Min

func Min[T Number](x, y T) T

Min returns the smaller of x or y.

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 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 Reverse

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

Reverse reverses a slice.

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 Shuffle

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

Shuffle shuffles a slice randomly.

func StdinIsPipe added in v2.0.3

func StdinIsPipe() bool

func StdoutIsTerminal added in v2.0.3

func StdoutIsTerminal() bool

func UnicodeBar added in v2.0.3

func UnicodeBar(width int) string

func UnicodeCategory added in v2.0.4

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"...

Types

type Number

type Number interface {
	constraints.Integer | constraints.Float
}

Jump to

Keyboard shortcuts

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