zen

package module
Version: v1.0.7 Latest Latest
Warning

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

Go to latest
Published: Jan 2, 2023 License: MIT Imports: 18 Imported by: 2

README

Zen

Zen is an utility-first package that provides a set of commonly used functions, helpers and extensions. Most of the functions are adapted to be used with html/template.

Motivation

We had too many cases of copy-pasting the same code between projects over and over again. So I decided to combine it all in one place.

Documentation

Code is well-documented, so it's pretty comfortable to use documentation provided by pkg.go.dev

Examples

Provided examples doesn't cover all the features of the library. Please refer to the documentation for details.

package main

import (
    "time"

    "git.sr.ht/~kyoto-framework/zen"
)

// Example of async function
func foo() zen.Future[string] {
    return zen.Async(func() (string, error) {
        // Imitate work
        time.Sleep(time.Second)
        // Return result
        return "bar", nil
    })
}

func main() {
    // Sample slice with zen.Range
    slice := zen.Range(1, 5) // []int{1, 2, 3, 4, 5}

    // Aggregatives
    zen.Min(slice) // 1
    zen.Max(slice) // 5
    zen.Avg(slice) // 3

    // Range operations
    zen.Filter(slice, func(v int) bool { return v < 3 }) // []int{1, 2}
    zen.Map(slice, func(v int) int { return v * 2 }) // []int{2, 4, 6, 8, 10}
    zen.In(1, slice) // true
    zen.Pop(slice, 1) // ([]int{1, 3, 4, 5}, 2)
    zen.Insert(slice, 1, 2) // []int{1, 2, 2, 3, 4, 5}
    zen.Last(slice) // 5
    zen.Any(slice, func(v int) bool { return v == 2 }) // true
    zen.All(slice, func(v int) bool { return v < 6 }) // true

    // Inline transformations
    zen.Ptr(1) // *int{1}  Inline pointer
    zen.Bool(3) // bool{true}
    zen.Int("5") // int{5}
    zen.Float64("6.5") // float64{6.5}
    zen.String(7) // string{"7"}

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

    // Must for opinionated panic handling
    zen.Must(strconv.Atoi("1")) // int{1}, without error

    // Await example
    futureFoo := foo() // It's not blocking
    println("foo call is not blocked")
    // Wait for result
    result, _ := zen.Await(futureFoo)
    println(result)
}

Documentation

Overview

Package zen is an utility-first package that provides a set of commonly used functions, helpers and extensions. Most of the functions are adapted to be used with `html/template`.

We had too many cases of copy-pasting the same code between projects over and over again. So we decided to combine it all in one place.

Aggregative

Library provides basic aggregative functions.

zen.Min(1, 2, 3) // 1
zen.Max(1, 2, 3) // 3
zen.Avg(1, 2, 3) // 2

Arithmetic

Library 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`). See Funcmap section for details.

Async

Library 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 any async/await syntax, your function must to return a Future, provided by Async function.

// Example asynchronous function
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.

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

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

// Define a sample untyped slice
values := []any{1, 2, 3}
// Casting example
castedValues := zen.CastSlice[int](values) // []int{1, 2, 3}

Errors

Library provides a simple helper functions to handle error cases, like Must or Ignore.

// Panic on error
value := zen.Must(strconv.Atoi("abc"))
// Empty value on error
value := zen.Ignore(strconv.Atoi("abc")) // 0

Funcmap

Library provides an utilities funcmap to be attached to template rendering. See FuncMap variable for details.

Strings

Zen provides some useful non-standard string formatting functions.

zen.Replace("Hello, 42 World!", "[0-9]+", "<number>") // Hello, <number> World!
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. Unfortunately, it's not syntax-level feature. That's why you can't use conditional code execution here.

// 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"}
// As far as it's not a syntax feature, code is executing in any case.
// These lines will panic, because values[0] is executing even if condition is matching first case.
values := []int{}
zen.Tr(len(values) == 0, 123, values[0])

Range

Some generic functions for basic slice operations.

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

Networking

Library provides a set of wrappers and builder in addition to default net/http package.

RequestBuilder is a builder with an ability to chain request definition and execution. You can initialize RequestBuilder with zen.Request function. It allows to set query, headers, body, almost everything in single line of code. Supports both setting values with structs/maps and native values (like url.Values for query). As far as RequestBuilder have an option to return *ResponseWrapper, you can chain both request building and response processing into single line.

// This request building chain will:
// - Parse initial values (method and url)
// - Set a query value "qval" for a key "qkey"
// - Set a header "hkey: hval"
// - Set an url encoded body and a header "Content-Type: application/x-www-form-urlencoded"
// - Build a resulting request and return
request := zen.Request("POST", "https://httpbin.org/post").
	Query("qkey", "qval").
	Header("hkey", "hval").
	Form(map[string]string{"fkey": "fval"}).
	Build()

// Request wrapper also have an inline execution option.
// This gives an ability to process response inline.
data := map[string]any{}
err := zen.Request("GET", "https://httpbin.org/get").
	Do().
	Success().
	Decode(&data).
	Ensure()
if err != nil {
	fmt.Println("Something went wrong: %v", err)
}

ResponseWrapper is a wrapper with an ability to chain response processing. You can initialize ResponseWrapper with a zen.Response function. It allows to operate with wrapped response in a more convenient way. Check status code, dump response to stdout for debug, convert body into map or decode directly into value. Almost everything in single line of code.

// Data holder
data := map[string]any{}
// This execution chain will:
// - Wrap response and error with zen.ResponseWrapper
// - Print raw response dump into stdout
// - Ensure status is between 200-299
// - Decode data into provided data holder (struct or map)
// - Panics, if something went wrong during processing
zen.Response(http.Get("https://httpbin.org/get")).
	Debug().Success().
	Decode(&data).
	Must()

Transform

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

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

View Source
var FuncMap = template.FuncMap{

	"html":     func(val string) template.HTML { return template.HTML(val) },
	"htmlattr": func(val string) template.HTMLAttr { return template.HTMLAttr(val) },
	"url":      func(val string) template.URL { return template.URL(val) },
	"css":      func(val string) template.CSS { return template.CSS(val) },
	"js":       func(val string) template.JS { return template.JS(val) },

	"compose": Compose,
	"ptr":     func(val any) any { return &val },
	"bool":    Bool,
	"int":     Int,
	"float":   Float64,
	"string":  String,
	"json":    JSON,
	"b64enc":  B64Dec,
	"b64dec":  B64Enc,

	"sum": SumRuntime,
	"sub": SubRuntime,
	"mul": MulRuntime,
	"div": DivRuntime,

	"contains": strings.Contains,
	"replace":  strings.ReplaceAll,
	"lower":    strings.ToLower,
	"upper":    strings.ToUpper,
	"title":    strings.Title,
	"trim":     strings.TrimSpace,

	"sprintf": fmt.Sprintf,

	"number":    FormatNumber,
	"numberP0":  FormatNumberP0,
	"numberP1":  FormatNumberP1,
	"numeral":   FormatNumberNumeral,
	"numeralP0": FormatNumberNumeralP0,
	"numeralP1": FormatNumberNumeralP1,

	"now":  func() time.Time { return time.Now() },
	"date": func(format string) string { return time.Now().Format(format) },

	"rng": Range,
	"in":  InRuntime,

	"env": os.Getenv,
}

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

Functions

func All

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

All ensures that all values from a given slice satisfies a given condition.

Usage:

All([]int{1, 2, 3}, func(v int) bool { return v > 0 }) // true

func Any

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

Any ensures that at least one value from a given slice satisfies a given condition.

Usage:

Any([]int{-1, 0, 1}, func(v int) bool { return v < 0 }) // true

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

Bool converts the given value to boolean.

Usage:

zen.Bool(4.5) // true

func Cached added in v1.0.4

func Cached[T any](expire time.Duration, fn cachedFunc[T]) cachedFunc[T]

Cached is a function wrapper with exprire duration setting. Consider it as a cached getter builder. As far as Cached doesn't support functions with arguments (it will require much more effort and complications), you'll need to create cached getter for each argument set. At least, until the creation of more advanced cached builder.

Usage:

getter := Cached(1 * time.Minute, func() (string, error) {
	time.Sleep(1 * time.Second) // Imitate some work
	return "Function cached result"
})
log.Println(getter())
log.Println(getter())

func Cartesian

func Cartesian[T any](slices ...[]T) (res [][]T)

Cartesian makes a product of two or more sets.

Usage:

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

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

CastSlice 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

Chunks generates a chunks with a given size from a given slice.

Usage:

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

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

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

Ignore is a helper that wraps a call to a function returning value and error and ignores if the error is non-nil.

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 Index added in v1.0.5

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

Index finds element index according to the given function. If nothing found, returns -1.

Usage:

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

func Insert

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

Insert injects a provided value into slice on the given index.

Usage:

Insert([]string{"b", "c"}, 0, "a") // []string{"a", "b", "c"}

func Int

func Int(val any) int

Int converts the given value to int.

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

Last takes a last element of a given slice.

Usage:

Last([]string{"a", "b", "c"}) // "c"

func Limit added in v1.0.6

func Limit[T any](slice []T, limit int) []T

Limit makes a slice subset of length is bigger than limit.

Usage:

Limit([]string{"a", "b", "c"}, 2) // []string{"a", "b"}

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 value and error 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)

Pop takes an last element from a slice (with deletion), or with a given index.

Usage:

a := []int{1, 2, 3}
b := Pop(a)     // 3
fmt.println(a)  // []int{1, 2}

func Ptr

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

Ptr makes a pointer for a 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 Replace added in v1.0.1

func Replace(s string, old string, new string) string

Replace is a replace function similar to strings.ReplaceAll, but with regex support.

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

func Unique added in v1.0.3

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

Unique returns a new slice with the unique slice values. Comparable value is defined by a given function.

Usage:

Unique([]int{1, 2, 2, 3}, func(v int) int { return v }) // []int{1, 2, 3}

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 RequestBuilder

type RequestBuilder struct {
	// contains filtered or unexported fields
}

RequestBuilder provides set of chainable functions to build a request and execute it.

func Request

func Request(method, url string) *RequestBuilder

Request initializes a *RequestBuilder with a given required parameters. See RequestBuilder for details.

func (*RequestBuilder) Async

func (r *RequestBuilder) Async() *Future[*ResponseWrapper]

Async wraps a request execution (Do) with a Future.

func (*RequestBuilder) Body

func (r *RequestBuilder) Body(body io.Reader) *RequestBuilder

Body sets a body as-is.

func (*RequestBuilder) Build

func (r *RequestBuilder) Build() *http.Request

Build composes provided parameters into *http.Request.

func (*RequestBuilder) Client

func (r *RequestBuilder) Client(client *http.Client) *RequestBuilder

Client sets a client, which will be used on request execution (with Do or Async methods).

func (*RequestBuilder) Do

Do builds an *http.Request and executes it with a provided client. If client wasn't provided, uses http.DefaultClient.

func (*RequestBuilder) Form

func (r *RequestBuilder) Form(body any) *RequestBuilder

Form transforms given object into url encoded string, wraps it with an io.Reader and sets as a request body. Also, it sets a Content-Type header. If body is not serializable with json, it panics.

func (*RequestBuilder) Header

func (r *RequestBuilder) Header(key, val string) *RequestBuilder

Header sets a header with a given parameters.

func (*RequestBuilder) HeaderMap

func (r *RequestBuilder) HeaderMap(headers map[string]string) *RequestBuilder

HeaderMap sets a header values with a given parameters, stored in map.

func (*RequestBuilder) HeaderMapFmt

func (r *RequestBuilder) HeaderMapFmt(headers map[string]any) *RequestBuilder

HeaderMapFmt formats and sets header values with a given parameters, stored in map.

func (*RequestBuilder) HeaderValues

func (r *RequestBuilder) HeaderValues(headers map[string][]string) *RequestBuilder

HeaderValues sets a headers as-is.

func (*RequestBuilder) JSON

func (r *RequestBuilder) JSON(body any) *RequestBuilder

JSON transforms given object into json, wraps it with an io.Reader and sets as a request body. Also, it sets a Content-Type header. If body is not serializable with json, it panics.

func (*RequestBuilder) Query

func (r *RequestBuilder) Query(key, val string) *RequestBuilder

Query sets a query value with a given parameters.

func (*RequestBuilder) QueryMap

func (r *RequestBuilder) QueryMap(values map[string]string) *RequestBuilder

QueryMap sets a query values with a given parameters, stored in map.

func (*RequestBuilder) QueryMapFmt

func (r *RequestBuilder) QueryMapFmt(values map[string]any) *RequestBuilder

QueryMapFmt formats and sets query values with a given parameters, stored in map.

func (*RequestBuilder) QueryStruct

func (r *RequestBuilder) QueryStruct(values any) *RequestBuilder

QueryStruct sets a query values with a given object. It transforms object into json and back into map to extract values, then acts in the same way as QueryMapFmt. If something goes wrong with marshalling, it panics.

func (*RequestBuilder) QueryValues

func (r *RequestBuilder) QueryValues(values urlpkg.Values) *RequestBuilder

QueryValues sets a query as-is.

func (*RequestBuilder) Text

func (r *RequestBuilder) Text(body string) *RequestBuilder

Text wraps a given string body parameter with an io.Reader and sets as a request body. Also, it sets a Content-Type header.

type ResponseWrapper

type ResponseWrapper struct {
	*http.Response
	// contains filtered or unexported fields
}

ResponseWrapper is a wrapper around http.Response. It provides a set of functions for a chained response processing.

func Response

func Response(resp *http.Response, err ...error) *ResponseWrapper

Response wraps *http.Response with own wrapper, providing extra functions. See ResponseWrapper for details.

func (*ResponseWrapper) Debug

func (r *ResponseWrapper) Debug() *ResponseWrapper

Debug prints the response to stdout. If something goes wrong during dump, chain execution will be stopped. Returns wrapper for chaining.

func (*ResponseWrapper) Decode

func (r *ResponseWrapper) Decode(target any) *ResponseWrapper

Decode detects response type and decodes it into target. If response type is not supported, or there is an error during decoding, chain execution will be stopped. Returns wrapper for chaining.

func (*ResponseWrapper) Ensure

func (r *ResponseWrapper) Ensure() error

Ensure is a chain closer. Ensures that there was no errors in processing chain. If not, returns an error.

func (*ResponseWrapper) Must

func (r *ResponseWrapper) Must()

Must is a chain closer. Ensures that there was no errors in processing chain. If not, it panics.

func (*ResponseWrapper) Success

func (r *ResponseWrapper) Success() *ResponseWrapper

Success ensures that response code is between 200 and 299. If not, chain execution will be stopped. Returns wrapper for chaining.

func (*ResponseWrapper) Text

func (r *ResponseWrapper) Text(target *string) *ResponseWrapper

Text reads response body as a text into provided target. If something goes wrong during reading, chain execution will be stopped. Returns wrapper for chaining.

Jump to

Keyboard shortcuts

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