x

package module
v3.0.0 Latest Latest
Warning

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

Go to latest
Published: Aug 22, 2023 License: MIT Imports: 17 Imported by: 0

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/v3" ]

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

func FormatByte[T Number](i T) string

func Goroutines

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

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 or n > math.MaxInt64.

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

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

Shuffle shuffles a slice randomly.

func StdinIsPipe

func StdinIsPipe() bool

func StdoutIsTerminal

func StdoutIsTerminal() bool

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

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
}

Jump to

Keyboard shortcuts

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