zen

package module
v0.0.0-...-38cf9b5 Latest Latest
Warning

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

Go to latest
Published: Jul 2, 2022 License: MIT Imports: 17 Imported by: 0

README

Kyoto project is moving from GitHub to sr.ht

https://sr.ht/~kyoto-framework/kyoto-framework/

Why?

Recent GitHub updates and overall company policy goes against my vision of open source projects. This opinion is shared by many people (https://sfconservancy.org/GiveUpGitHub/#ICE-contract-details). So I decided to move the project to sr.ht, which policy and actions are quite more transparent.

How?

As far as a go packaging system makes host changing painful enough, there is no chance to keep old versions on the new host. I'm not going to do everything at once and definitely not going to delete the project from GitHub in nearest 2 months. But the development of new features and versions will be continued only on sr.ht. Current projects on GitHub will be archived and removed after ~2 months.

What I need to do?

If you're using version 0.x, please, make a fork, or create a local project copy. For those who are using 1.x, it's enough to switch references from "github.com/kyoto-framework" to "git.sr.ht/~kyoto-framework".

How to contribute?

sr.ht uses mailing lists for communication, announcements, patches etc. There are no PRs like GitHub. I don't know much about it, but I'm going to dig into it in the near future (https://man.sr.ht/lists.sr.ht/). For now, those who want to contribute, I'll just add read/write permissions to the project.

Documentation

Overview

-

Aggregative

Zen provides some generic aggregative functions for slices.

-

Arithmetic

Zen provides simple arithmetic functions for sets of values: Sum, Sub, Mul, Div. Main point is to provide runtime template functions (which are missing in the built-in html/template).

-

Async

Zen provides a way to define and run asynchronous functions. It's based on Go's standard goroutines and channels. Future object holds value channel and error. It's used as an awaitable object. As far as Go is not provides an async/await syntax, your function must to return a Future, provided by Async function.

Example:

func Foo() *zen.Future[string] {
	return zen.Async(func() (string, error) {
		return "Bar", nil
	})
}

func main() {
	// Non-blocking calls
	fbar1 := Foo()
	fbar2 := Foo()
	// Await for results (errors are passed to simplify example)
	bar1, _ := zen.Await(fbar1)
	bar2, _ := zen.Await(fbar2)
}

-

Atomic

Zen provides a generic atomic wrapper, based on RWMutex. Usually, actions are performed with Get and Set methods. For complex cases (like simultaneous Get and Set), Atomic provides a Context method which allows to pass a function and lock a mutex for the duration of the function.

Example:

func main() {
	// Initialize atomic value
	value := Atomic[int]{}
	value.Set(1)

	// Get and check value
	if value.Get() == 1 {
		println("It's OK")
	}

	// Pass a context function, which will obtain a lock
	value.Context(func(value int, set func(value int)) {
		if value == 1 {
			set(2)
		}
	})
}

-

Cast

Zen provides a comfortable way to work with slices casting ([]any).

Example:

func main() {
	// Define a sample slice
	values := []any{1, 2, 3}
	// Demonstrate casting
	castedValues := zen.CastSlice[int](values) []int{1, 2, 3}
}

-

Format

Zen provides some useful formatting functions.

Examples:

func main() {
	zen.FormatNumber(12345.456, 0, "$", "") // "$12,345"
	zen.FormatNumberP0(12345.456) // "12,345"
	zen.FormatNumberP1(12345.456) // "12,345.4"
	zen.FormatNumberNumeral(12345.456, 0) // "12k"
	zen.FormatNumberNumeralP0(12345.456) // "12k"
	zen.FormatNumberNumeralP1(12345.456) // "12.3k"
}

-

Logical

Logical expressions from another languages, but missing in Go.

Examples:

func main() {
	// Go is not supporting "or" for values, like (0 || 1)
	zen.Or("", "asd") // string{"asd"}
	// Go doesn't have "ternary" operator, like (true ? "asd" : "qwe")
	zen.Tr(false, "asd", "qwe") // string{"qwe"}
}

-

Must

Zen provides a simple helper function that wraps a call to a function returning value and error, and panics if the error is non-nil.

Example:

func main() {
	zen.Must(strconv.Atoi("asd")) // panic
}

-

Range

Zen provides some generic functions for basic slice operations.

Examples:

func main() {
	// Creating an integers slice with a Range function
	var slice = zen.Range(1, 5) // []int{1, 2, 3, 4, 5}

	// Filtering
	zen.Filter(slice, func(v int) bool { return v < 3 }) // []int{1, 2}

	// Creating a new slice, based on existing one with a Map function
	zen.Map(slice, func(v int) int { return v * 2 }) // []int{2, 4, 6, 8, 10}

	// Checking if an element is in the slice
	zen.In(1, slice) // true

	// Pop an element at the given index from the slice (returns a new slice and the value)
	zen.Pop(slice, 1) // ([]int{1, 3, 4, 5}, 2)

	// Insert an element at the given index in the slice (returns a new slice)
	zen.Insert(slice, 1, 2) // []int{1, 2, 2, 3, 4, 5}

	// Get the last element from the slice
	zen.Last(slice) // 5

	// Check if any element in the slice matches the given function
	zen.Any(slice, func(v int) bool { return v == 2 }) // true

	// Check if all elements in the slice match the given function
	zen.All(slice, func(v int) bool { return v < 6 }) // true
}

-

Response

Zen provides a *http.Response wrapper with a few useful extra methods. It allows to operate with wrapped response in a more convenient way. Check status code, dump response to stdout for debug, convert into map or decode directly into value. Almost everything in single line of code.

Example:

func main() {
	// Make a request
	resp, err := http.Get("https://example.com/api/json")
	if err != nil {
		panic(err)
	}
	// Dump, check, convert to map
	data := zen.Response(resp).Debug().Must().Map()
}

-

Transform

Zen provides a number of functions that can be used to transform data into different types and forms. Most of these functions are working with base data types.

Examples:

func main() {
	// Common data types transformations
	numptr := zen.Ptr(1) // *int{1}  Inline pointer
	boolval := zen.Bool(3) // bool{true}
	intval := zen.Int("5") // int{5}
	floatval := zen.Float64("6.5") // float64{6.5}
	strval := zen.String(7) // string{"7"}

	// Map composition (useful for templates)
	resmap := zen.Compose("foo", 1, "bar", "2") // map[any]any{"foo": 1, "bar": "2"}

	// JSON
	resjson := zen.JSON(resmap) // string{`{"foo": 1, "bar": "2"}`}

	// Base64
	resbase64 := zen.B64Enc(resjson) // string{`eyJmb28iOiAxLCAiYmFyIjogIjIifQ==`}
	resbase64dec := string(zen.B64Dec(resbase64)) // string{`{"foo": 1, "bar": "2"}`}
}

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func All

func All[T any](slice []T, fn func(v T) bool) bool

func Any

func Any[T any](slice []T, fn func(v T) bool) bool

func Avg

func Avg[T constraints.Integer | constraints.Float](vals ...T) T

Avg returns the average value of the given values.

Usage:

zen.Avg(1, 2, 3, slice...) // 2

func Await

func Await[T any](f *Future[T]) (T, error)

Await for a future object.

func B64Dec

func B64Dec(val string) []byte

B64Dec converts the given base64 string to a value (bytes)

Usage:

// Code
zen.B64Dec("Zm9v") // []byte("foo")
// Template
{{ b64dec "Zm9v" }}

func B64Enc

func B64Enc(val any) string

B64Enc converts the given value (bytes or string) to a base64 string.

Usage:

// Code
zen.B64Enc([]byte("foo")) // "Zm9v"
Template
{{ b64enc "foo" }}

func Bool

func Bool(val any) bool

Int converts the given value to a boolean.

Usage:

zen.Bool(4.5) // true

func CastPSlice

func CastPSlice[T any](slice []any) []*T

CastPSlice is a function to cast a slice of any values ([]any) to a slice of the given type pointers.

Usage:

zen.CastPSlice(int)([]any{1, 2, nil}) []*int{1, 2, nil}

func CastSlice

func CastSlice[T any](slice []any) []T

CastSice is a function to cast a slice of any values ([]any) to a slice of the given type.

Usage:

zen.CastSlice[int]([]any{1, 2, 3}) // []int{1, 2, 3}

func Chunks

func Chunks[T any](slice []T, size int) [][]T

func Compose

func Compose(vals ...any) map[any]any

Compose makes a map with the given keys and values. Useful as a template function to pass multiple values to a template. Based on even and odd values.

Usage:

// Code
zen.Compose("foo", 1, "bar", 2) // map[any]any{"foo": 1, "bar": 2}
// Template
{{ compose "foo" 1 "bar" 2 }}

func Div

func Div[T constraints.Integer | constraints.Float](vals ...T) T

Div returns the division of the given values to the first one.

Usage:

// Code
zen.Div(3, 2, 1, slice...) // 1.5
// Templates
{{ sum 3 2 1 }} // 1.5

func DivRuntime

func DivRuntime(vals ...any) any

DivRuntime is a runtime analogue of Div (made to be compatible with templates).

func Filter

func Filter[T any](slice []T, fn func(v T) bool) []T

Filter returns filtered slice according to the given function.

Usage:

Filter([]int{1, 2, 3}, func(v int) bool { return v < 3 }) // []int{1, 2}

func Float64

func Float64(val any) float64

Float64 converts the given value to a float64.

Usage:

zen.Float64("5") // 5.0

func FormatNumber

func FormatNumber(number float64, precision int, prefix, suffix string) string

FormatNumber returns a string representation of the given number in specified format.

Usage:

zen.FormatNumber(12345.456, 0, "$", "") // "$12,345"

func FormatNumberNumeral

func FormatNumberNumeral(number float64, precision int) string

FormatNumberNumeral returns a shorten, string representation of the given number.

Usage:

zen.FormatNumberNumeral(12345.456, 0) // "12k"

func FormatNumberNumeralP0

func FormatNumberNumeralP0(number float64) string

FormatNumberNumeralP0 is a wrapper around FormatNumberNumeral with 0 precision.

Usage:

zen.FormatNumberNumeralP0(12345.456) // "12k"

func FormatNumberNumeralP1

func FormatNumberNumeralP1(number float64) string

FormatNumberNumeralP1 is a wrapper around FormatNumberNumeral with 1 precision.

Usage:

zen.FormatNumberNumeralP1(12345.456) // "12.3k"

func FormatNumberP0

func FormatNumberP0(number float64) string

FormatNumberP0 is a wrapper around FormatNumber with 0 precision and no prefix or suffix.

Usage:

zen.FormatNumberP0(12345.456) // "12,345"

func FormatNumberP1

func FormatNumberP1(number float64) string

FormatNumberP1 is a wrapper around FormatNumber with 1 precision and no prefix or suffix.

Usage:

zen.FormatNumberP1(12345.456) // "12,345.4"

func FuncMap

func FuncMap() template.FuncMap

FuncMap is a map of functions to be used in templates.

func In

func In[T comparable](val T, slice []T) bool

In returns true if the given value is in the given slice.

Usage:

In(1, []int{1, 2, 3}) // true

func InRuntime

func InRuntime(val any, slice any) bool

InRuntime is a runtime analogue of In (made to be compatible with templates).

func Insert

func Insert[T any](slice []T, index int, value T) []T

func Int

func Int(val any) int

Int converts the given value to an integeter.

Usage:

zen.Int("123") // 123

func JSON

func JSON(val any) string

JSON is a function that converts the given value to a JSON string. Useful as a template function.

Usage:

// Code
zen.JSON(map[any]any{"foo": 1, "bar": 2}) // {"foo":1,"bar":2}
// Template
{{ json .Value }}

func Last

func Last[T any](slice []T) T

func Map

func Map[T1 any, T2 any](slice []T1, fn func(v T1) T2) []T2

Map returns a new slice with the results of applying the given function to each element in the given slice.

Usage:

Map([]string{"asd", "qwe"}, func(v string) int { return len(v) }) // []int{3, 3}

func Max

func Max[T constraints.Ordered](vals ...T) T

Max returns the maximum value of the given values.

Usage:

zen.Max(1, 2, 3, slice...) // 3

func Min

func Min[T constraints.Ordered](vals ...T) T

Min returns the minimum value of the given values.

Usage:

zen.Min(1, 2, 3, slice...) // 1

func Mul

func Mul[T constraints.Integer | constraints.Float](vals ...T) T

Mul returns the multiplication of the given values.

Usage:

// Code
zen.Mul(1, 2, 3, slice...) // 6
// Templates
{{ mul 1 2 3 }} // 6

func MulRuntime

func MulRuntime(vals ...any) any

MulRuntime is a runtime analogue of Mul (made to be compatible with templates).

func Must

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

Must is a helper that wraps a call to a function returning and panics if the error is non-nil.

func Or

func Or[T comparable](a, b T) T

Or acts like "||" for values in any other language. Unfortuantely, in Go this operator only works for conditions.

Usage:

zen.Or(0, 1) // 1

func Pop

func Pop[T any](slice []T, index ...int) ([]T, T)

func Ptr

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

Ptr makes a pointer to the given value.

Usage:

zen.Ptr(1) // *int 1

func Range

func Range(from, to int) []int

Range returns a new slice of integers in the given range (from, to).

Usage:

Range(1, 5) // []int{1, 2, 3, 4, 5}

func String

func String(val any) string

String converts the given value to a string.

Usage:

zen.String(1) // "1"

func Sub

func Sub[T constraints.Integer | constraints.Float](vals ...T) T

Sub returns the subtraction of the given values from the first one.

Usage:

// Code
zen.Sub(3, 2, 1, slice...) // 0
// Templates
{{ sub 3 2 1 }} // 0

func SubRuntime

func SubRuntime(vals ...any) any

SubRuntime is a runtime analogue of Sub (made to be compatible with templates).

func Sum

func Sum[T constraints.Integer | constraints.Float | string](vals ...T) T

Sum returns the sum of the given values.

Usage:

// Code
zen.Sum(1, 2, 3, slice...) // 6
// Templates
{{ sum 1 2 3 }} // 6

func SumRuntime

func SumRuntime(vals ...any) any

SumRuntime is a runtime analogue of Sum (made to be compatible with templates).

func Tr

func Tr[T comparable](condition bool, v1, v2 T) T

Tr acts like a ternary operator in other languages. Unfortuantely, Go doesn't have this operator.

Usage:

zen.Tr(false, "asd", "qwe") // string{"qwe"}

Types

type Atomic

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

func (*Atomic[T]) Context

func (a *Atomic[T]) Context(c func(value T, set func(value T)))

func (*Atomic[T]) Get

func (a *Atomic[T]) Get() T

func (*Atomic[T]) Set

func (a *Atomic[T]) Set(value T)

type Future

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

Future is an awaitable object. Behavior is similar to JS Promise.

func Async

func Async[T any](f func() (T, error)) *Future[T]

Async runs a function in a goroutine and returns Future object for it.

func (*Future[T]) MarshalJSON

func (f *Future[T]) MarshalJSON() ([]byte, error)

MarshalJSON implements future marshalling.

func (*Future[T]) UnmarshalJSON

func (c *Future[T]) UnmarshalJSON(data []byte) error

MarshalJSON implements future unmarshalling.

type QueryWrapper

type QueryWrapper struct {
	url.Values
}

QueryWrapper type is a wrapper for url.Values. It provides a few useful extra methods.

func Query

func Query(q url.Values) *QueryWrapper

func (*QueryWrapper) Unmarshal

func (q *QueryWrapper) Unmarshal(target any) error

Unmarshal helps to parse url.Values into a struct. Slightly modified version of github.com/knadh/querytostruct

Example:

var target struct {
	Foo string `query:"foo"`
	Bar int `query:"bar"`
}

q, _ := url.ParseQuery("foo=asdqwe&bar=123")
kyoto.Query(q).Unmarshal(&target)

type ResponseWrapper

type ResponseWrapper struct {
	*http.Response
}

ResponseWrapper is a wrapper for http.Response. It provides a few useful extra methods.

func Response

func Response(resp *http.Response) *ResponseWrapper

Response wraps *http.Response with own wrapper, providing extra methods.

func (*ResponseWrapper) Debug

func (r *ResponseWrapper) Debug() *ResponseWrapper

Debug prints the response to stdout. Returns itself for chaining.

func (*ResponseWrapper) Decode

func (r *ResponseWrapper) Decode(target any)

Decode detects response type and decodes it to target. If the response type is not supported, it panics.

func (*ResponseWrapper) Map

func (r *ResponseWrapper) Map() map[string]any

Map detects response type and decodes it to map[string]any{}. If the response type is not supported, it panics.

func (*ResponseWrapper) Must

func (r *ResponseWrapper) Must() *ResponseWrapper

Must ensures that response code is between 200 and 299. If not, it panics. Returns itself for chaining.

func (*ResponseWrapper) Text

func (r *ResponseWrapper) Text() string

Text reads response body as a text. If something wrong, it panics.

Jump to

Keyboard shortcuts

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