function

package module
v0.0.0-...-da6248e Latest Latest
Warning

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

Go to latest
Published: Mar 5, 2024 License: MIT Imports: 19 Imported by: 4

README

go-function

Wrapping Go functions as HTTP handlers and CLI commands

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	CatchHTTPHandlerPanics = true
	PrettyPrint            = true
	PrettyPrintIndent      = "  "
)
View Source
var (
	StringScanners *TypeStringScanners = NewTypeStringScanners(StringScannerFunc(DefaultScanString))

	ArgNameTag        = "arg"
	ArgDescriptionTag = "desc"

	// TimeFormats used in that order to try parse time strings.
	// If a time format has not time zone part,
	// then the date is returned in the local time zone.
	TimeFormats = []string{
		time.RFC3339Nano,
		time.RFC3339,
		time.DateOnly + " 15:04:05.999999999 -0700 MST",
		time.DateTime,
		time.DateOnly + " 15:04",
		time.DateOnly + "T15:04",
		time.DateOnly,
	}
)
View Source
var (
	// ErrTypeNotSupported indicates that a type is not supported
	ErrTypeNotSupported = errors.New("type not supported")

	// HandleErrorHTTP will handle a non nil error by writing it to the response.
	// The default is to use github.com/ungerik/go-httpx/httperr.DefaultHandler.
	HandleErrorHTTP = func(err error, response http.ResponseWriter, request *http.Request) {
		if err != nil {
			httperr.DefaultHandler.HandleError(err, response, request)
		}
	}
)
View Source
var RespondNothing respondNothing

Functions

func CallFunctionWithJSONArgs

func CallFunctionWithJSONArgs(ctx context.Context, f Wrapper, jsonObject []byte) (results []any, err error)

func DefaultScanString

func DefaultScanString(sourceStr string, destPtr any) (err error)

func DetectContentType

func DetectContentType(data []byte) string

DetectContentType tries to detect the MIME content-type of data, or returns "application/octet-stream" if none could be identified.

func HTTPHandler

func HTTPHandler(getArgs HTTPRequestArgsGetter, function CallWithNamedStringsWrapper, resultsWriter HTTPResultsWriter, errHandlers ...httperr.Handler) http.HandlerFunc

func HTTPHandlerNoWrapper

func HTTPHandlerNoWrapper(function func(context.Context) ([]byte, error), resultsWriter HTTPResultsWriter, errHandlers ...httperr.Handler) http.HandlerFunc

HTTPHandlerNoWrapper returns an http.Handler for a function without a wrapper of type func(context.Context) ([]byte, error) that returns response bytes.

func HTTPRequestBodyJSONFieldsAsArgs

func HTTPRequestBodyJSONFieldsAsArgs(request *http.Request) (map[string]string, error)

func HTTPRequestMultipartFormArgs

func HTTPRequestMultipartFormArgs(request *http.Request) (map[string]string, error)

HTTPRequestMultipartFormArgs returns the multipart form values of the request as string map. If a form field has multiple values, they are joined with ";".

func HTTPRequestQueryArgs

func HTTPRequestQueryArgs(request *http.Request) (map[string]string, error)

HTTPRequestQueryArgs returns the query params of the request as string map. If a query param has multiple values, they are joined with ";".

func ReflectType

func ReflectType[T any]() reflect.Type

ReflectType returns the reflect.Type of the generic type T

func ScanString

func ScanString(sourceStr string, destPtr any) error

ScanString uses the configured DefaultStringScanner to scan sourceStr to destPtr.

func ScanStrings

func ScanStrings(sourceStrings []string, destPtrs ...any) error

ScanStrings uses the configured DefaultStringScanner to scan sourceStrings to destPtrs. If the number of sourceStrings and destPtrs is not identical then only the lower number of either will be scanned.

Types

type CallWithJSONWrapper

type CallWithJSONWrapper interface {
	CallWithJSON(ctx context.Context, argsJSON []byte) (results []any, err error)
}

func CallWithJSONWrapperTODO

func CallWithJSONWrapperTODO(function any) CallWithJSONWrapper

type CallWithJSONWrapperFunc

type CallWithJSONWrapperFunc func(ctx context.Context, argsJSON []byte) (results []any, err error)

func (CallWithJSONWrapperFunc) CallWithJSON

func (f CallWithJSONWrapperFunc) CallWithJSON(ctx context.Context, argsJSON []byte) (results []any, err error)

type CallWithNamedStringsWrapper

type CallWithNamedStringsWrapper interface {
	CallWithNamedStrings(ctx context.Context, args map[string]string) (results []any, err error)
}

func CallWithNamedStringsWrapperTODO

func CallWithNamedStringsWrapperTODO(function any) CallWithNamedStringsWrapper

type CallWithNamedStringsWrapperFunc

type CallWithNamedStringsWrapperFunc func(ctx context.Context, args map[string]string) (results []any, err error)

func (CallWithNamedStringsWrapperFunc) CallWithNamedStrings

func (f CallWithNamedStringsWrapperFunc) CallWithNamedStrings(ctx context.Context, args map[string]string) (results []any, err error)

type CallWithStringsWrapper

type CallWithStringsWrapper interface {
	CallWithStrings(ctx context.Context, args ...string) (results []any, err error)
}

func CallWithStringsWrapperTODO

func CallWithStringsWrapperTODO(function any) CallWithStringsWrapper

type CallWithStringsWrapperFunc

type CallWithStringsWrapperFunc func(ctx context.Context, args ...string) (results []any, err error)

func (CallWithStringsWrapperFunc) CallWithStrings

func (f CallWithStringsWrapperFunc) CallWithStrings(ctx context.Context, args ...string) (results []any, err error)

type CallWrapper

type CallWrapper interface {
	Call(ctx context.Context, args []any) (results []any, err error)
}

func CallWrapperTODO

func CallWrapperTODO(function any) CallWrapper

type CallWrapperFunc

type CallWrapperFunc func(ctx context.Context, args []any) (results []any, err error)

func (CallWrapperFunc) Call

func (f CallWrapperFunc) Call(ctx context.Context, args []any) (results []any, err error)

type Description

type Description interface {
	Name() string
	String() string

	NumArgs() int
	ContextArg() bool
	NumResults() int
	ErrorResult() bool

	ArgNames() []string
	ArgDescriptions() []string
	ArgTypes() []reflect.Type
	ResultTypes() []reflect.Type
}

func ReflectDescription

func ReflectDescription(name string, f any) (Description, error)

type ErrParseArgJSON

type ErrParseArgJSON struct {
	Err  error
	Func fmt.Stringer
	Arg  string
}

func NewErrParseArgJSON

func NewErrParseArgJSON(err error, f fmt.Stringer, arg string) ErrParseArgJSON

func (ErrParseArgJSON) Error

func (e ErrParseArgJSON) Error() string

func (ErrParseArgJSON) Unwrap

func (e ErrParseArgJSON) Unwrap() error

type ErrParseArgString

type ErrParseArgString struct {
	Err  error
	Func fmt.Stringer
	Arg  string
}

func NewErrParseArgString

func NewErrParseArgString(err error, f fmt.Stringer, arg string) ErrParseArgString

func (ErrParseArgString) Error

func (e ErrParseArgString) Error() string

func (ErrParseArgString) Unwrap

func (e ErrParseArgString) Unwrap() error

type ErrParseArgsJSON

type ErrParseArgsJSON struct {
	Err  error
	Func fmt.Stringer
	JSON string
}

func NewErrParseArgsJSON

func NewErrParseArgsJSON(err error, f fmt.Stringer, argsJSON []byte) ErrParseArgsJSON

func (ErrParseArgsJSON) Error

func (e ErrParseArgsJSON) Error() string

func (ErrParseArgsJSON) Unwrap

func (e ErrParseArgsJSON) Unwrap() error

type HTTPRequestArgsGetter

type HTTPRequestArgsGetter func(*http.Request) (map[string]string, error)

func HTTPRequestArg

func HTTPRequestArg(name, value string) HTTPRequestArgsGetter

func HTTPRequestArgs

func HTTPRequestArgs(args map[string]string) HTTPRequestArgsGetter

func HTTPRequestBodyAsArg

func HTTPRequestBodyAsArg(name string) HTTPRequestArgsGetter

func MergeHTTPRequestArgs

func MergeHTTPRequestArgs(getters ...HTTPRequestArgsGetter) HTTPRequestArgsGetter

type HTTPResultsWriter

type HTTPResultsWriter interface {
	WriteResults(results []any, resultErr error, response http.ResponseWriter, request *http.Request) error
}

func RespondContentType

func RespondContentType(contentType string) HTTPResultsWriter

type HTTPResultsWriterFunc

type HTTPResultsWriterFunc func(results []any, resultErr error, response http.ResponseWriter, request *http.Request) error
var RespondDetectContentType HTTPResultsWriterFunc = func(results []any, resultErr error, response http.ResponseWriter, request *http.Request) error {
	if resultErr != nil || request.Context().Err() != nil {
		return resultErr
	}
	if len(results) != 1 {
		return fmt.Errorf("RespondDetectContentType needs 1 result, got %d", len(results))
	}
	data, ok := results[0].([]byte)
	if !ok {
		return fmt.Errorf("RespondDetectContentType needs []byte result, got %T", results[0])
	}

	response.Header().Add("Content-Type", DetectContentType(data))
	_, err := response.Write(data)
	return err
}
var RespondHTML HTTPResultsWriterFunc = func(results []any, resultErr error, response http.ResponseWriter, request *http.Request) error {
	if resultErr != nil || request.Context().Err() != nil {
		return resultErr
	}
	var buf bytes.Buffer
	for _, result := range results {
		if b, ok := result.([]byte); ok {
			buf.Write(b)
		} else {
			fmt.Fprint(&buf, result)
		}
	}
	response.Header().Add("Content-Type", contenttype.HTML)
	_, err := response.Write(buf.Bytes())
	return err
}
var RespondJSON HTTPResultsWriterFunc = func(results []any, resultErr error, response http.ResponseWriter, request *http.Request) error {
	if resultErr != nil || request.Context().Err() != nil {
		return resultErr
	}

	if len(results) == 0 {
		return nil
	}

	response.Header().Set("Content-Type", contenttype.JSON)

	if len(results) == 1 {
		b, err := encodeJSON(results[0])
		if err != nil {
			return err
		}
		_, err = response.Write(b)
		return err
	}

	b, err := encodeJSON(results)
	if err != nil {
		return err
	}
	_, err = response.Write(b)
	return err
}
var RespondPlaintext HTTPResultsWriterFunc = func(results []any, resultErr error, response http.ResponseWriter, request *http.Request) error {
	if resultErr != nil || request.Context().Err() != nil {
		return resultErr
	}
	var buf bytes.Buffer
	for _, result := range results {
		if b, ok := result.([]byte); ok {
			buf.Write(b)
		} else {
			fmt.Fprint(&buf, result)
		}
	}
	response.Header().Add("Content-Type", contenttype.PlainText)
	_, err := response.Write(buf.Bytes())
	return err
}
var RespondXML HTTPResultsWriterFunc = func(results []any, resultErr error, response http.ResponseWriter, request *http.Request) error {
	if resultErr != nil || request.Context().Err() != nil {
		return resultErr
	}
	var buf []byte
	for _, result := range results {
		b, err := encodeXML(result)
		if err != nil {
			return err
		}
		buf = append(buf, b...)
	}
	response.Header().Set("Content-Type", contenttype.XML)
	_, err := response.Write(buf)
	return err
}

func RespondBinary

func RespondBinary(contentType string) HTTPResultsWriterFunc

RespondBinary responds with contentType using the binary data from results of type []byte, string, or io.Reader.

func RespondJSONField

func RespondJSONField(fieldName string) HTTPResultsWriterFunc

func (HTTPResultsWriterFunc) WriteResults

func (f HTTPResultsWriterFunc) WriteResults(results []any, resultErr error, response http.ResponseWriter, request *http.Request) error

type JSONArgsFunc

type JSONArgsFunc func(ctx context.Context, jsonObject []byte) error

func NewJSONArgsFunc

func NewJSONArgsFunc(f Wrapper, resultsHandlers ...ResultsHandler) JSONArgsFunc

type Logger

type Logger interface {
	Printf(format string, args ...any)
}

Logger interface

type NamedStringArgsFunc

type NamedStringArgsFunc func(ctx context.Context, args map[string]string) error

func NewNamedStringArgsFunc

func NewNamedStringArgsFunc(f CallWithNamedStringsWrapper, resultsHandlers ...ResultsHandler) NamedStringArgsFunc

type PrintlnText

type PrintlnText string

PrintlnText prints a fixed string if a command returns without an error

func (PrintlnText) HandleResults

func (t PrintlnText) HandleResults(ctx context.Context, results []any, resultErr error) error

type RespondRedirect

type RespondRedirect string

RespondRedirect implements HTTPResultsWriter and http.Handler with for a redirect URL string. The redirect will be done with HTTP status code 302: Found.

func (RespondRedirect) ServeHTTP

func (re RespondRedirect) ServeHTTP(response http.ResponseWriter, request *http.Request)

func (RespondRedirect) WriteResults

func (re RespondRedirect) WriteResults(results []any, resultErr error, response http.ResponseWriter, request *http.Request) error

type RespondRedirectFunc

type RespondRedirectFunc func(request *http.Request) (url string, err error)

RespondRedirectFunc implements HTTPResultsWriter and http.Handler with a function that returns the redirect URL. The redirect will be done with HTTP status code 302: Found.

func (RespondRedirectFunc) ServeHTTP

func (f RespondRedirectFunc) ServeHTTP(response http.ResponseWriter, request *http.Request)

func (RespondRedirectFunc) WriteResults

func (f RespondRedirectFunc) WriteResults(results []any, resultErr error, response http.ResponseWriter, request *http.Request) error

type RespondStaticHTML

type RespondStaticHTML string

func (RespondStaticHTML) ServeHTTP

func (html RespondStaticHTML) ServeHTTP(response http.ResponseWriter, _ *http.Request)

func (RespondStaticHTML) WriteResults

func (html RespondStaticHTML) WriteResults(results []any, resultErr error, response http.ResponseWriter, request *http.Request) error

type RespondStaticJSON

type RespondStaticJSON string

func (RespondStaticJSON) ServeHTTP

func (json RespondStaticJSON) ServeHTTP(response http.ResponseWriter, _ *http.Request)

func (RespondStaticJSON) WriteResults

func (json RespondStaticJSON) WriteResults(results []any, resultErr error, response http.ResponseWriter, request *http.Request) error

type RespondStaticPlaintext

type RespondStaticPlaintext string

func (RespondStaticPlaintext) ServeHTTP

func (text RespondStaticPlaintext) ServeHTTP(response http.ResponseWriter, _ *http.Request)

func (RespondStaticPlaintext) WriteResults

func (text RespondStaticPlaintext) WriteResults(results []any, resultErr error, response http.ResponseWriter, request *http.Request) error

type RespondStaticXML

type RespondStaticXML string

func (RespondStaticXML) ServeHTTP

func (xml RespondStaticXML) ServeHTTP(response http.ResponseWriter, _ *http.Request)

func (RespondStaticXML) WriteResults

func (xml RespondStaticXML) WriteResults(results []any, resultErr error, response http.ResponseWriter, request *http.Request) error

type ResultsHandler

type ResultsHandler interface {
	HandleResults(ctx context.Context, results []any, resultErr error) error
}

type ResultsHandlerFunc

type ResultsHandlerFunc func(ctx context.Context, results []any, resultErr error) error
var Println ResultsHandlerFunc = func(ctx context.Context, results []any, resultErr error) error {
	if resultErr != nil {
		return resultErr
	}
	results, err := makeResultsPrintable(results)
	if err != nil || len(results) == 0 {
		return err
	}
	for _, r := range results {
		_, err = fmt.Println(r)
		if err != nil {
			return err
		}
	}
	return nil
}

Println calls fmt.Println for every result

func LogTo

func LogTo(logger Logger) ResultsHandlerFunc

LogTo calls logger.Printf(fmt.Sprintln(results...))

func LogWithPrefixTo

func LogWithPrefixTo(prefix string, logger Logger) ResultsHandlerFunc

LogWithPrefixTo calls logger.Printf(fmt.Sprintln(results...)) with prefix prepended to the results

func PrintTo

func PrintTo(writer io.Writer) ResultsHandlerFunc

PrintTo calls fmt.Fprint on writer with the result values as varidic arguments

func PrintlnTo

func PrintlnTo(writer io.Writer) ResultsHandlerFunc

PrintlnTo calls fmt.Fprintln on writer for every result

func PrintlnWithPrefix

func PrintlnWithPrefix(prefix string) ResultsHandlerFunc

PrintlnWithPrefix calls fmt.Println(prefix, result) for every result value

func PrintlnWithPrefixTo

func PrintlnWithPrefixTo(prefix string, writer io.Writer) ResultsHandlerFunc

PrintlnWithPrefixTo calls fmt.Fprintln(writer, prefix, result) for every result value

func (ResultsHandlerFunc) HandleResults

func (f ResultsHandlerFunc) HandleResults(ctx context.Context, results []any, resultErr error) error

type StringArgsFunc

type StringArgsFunc func(ctx context.Context, args ...string) error

func NewStringArgsFunc

func NewStringArgsFunc(f CallWithStringsWrapper, resultsHandlers ...ResultsHandler) StringArgsFunc

type StringScanner

type StringScanner interface {
	ScanString(sourceStr string, destPtr any) error
}

type StringScannerFunc

type StringScannerFunc func(sourceStr string, destPtr any) error

func (StringScannerFunc) ScanString

func (f StringScannerFunc) ScanString(sourceStr string, destPtr any) error

type TypeStringScanners

type TypeStringScanners struct {
	Types      map[reflect.Type]StringScanner
	Interfaces map[reflect.Type]StringScanner
	Kinds      map[reflect.Kind]StringScanner
	Default    StringScanner
}

func NewTypeStringScanners

func NewTypeStringScanners(defaultScanner StringScanner) *TypeStringScanners

func (*TypeStringScanners) ScanString

func (s *TypeStringScanners) ScanString(sourceStr string, destPtr any) error

func (*TypeStringScanners) WithDefaultScanner

func (s *TypeStringScanners) WithDefaultScanner(scanner StringScanner) *TypeStringScanners

func (*TypeStringScanners) WithInterfaceTypeScanner

func (s *TypeStringScanners) WithInterfaceTypeScanner(destImplsInterface reflect.Type, scanner StringScanner) *TypeStringScanners

func (*TypeStringScanners) WithKindScanner

func (s *TypeStringScanners) WithKindScanner(destKind reflect.Kind, scanner StringScanner) *TypeStringScanners

func (*TypeStringScanners) WithTypeScanner

func (s *TypeStringScanners) WithTypeScanner(destType reflect.Type, scanner StringScanner) *TypeStringScanners

type Wrapper

func MustReflectWrapper

func MustReflectWrapper(function any, argNames ...string) Wrapper

MustReflectWrapper calls ReflectWrapper and panics any error.

func NoArgNoResultWrapper

func NoArgNoResultWrapper(name string, call func()) Wrapper

NoArgNoResultWrapper returns a Wrapper for a function call without arguments and without results.

func ReflectWrapper

func ReflectWrapper(function any, argNames ...string) (Wrapper, error)

ReflectWrapper returns a Wrapper for the passed function using reflection and the passed argNames. The number of passed argNames must match the number of function arguments. Except when the function only has one argument of type context.Context then "ctx" is assumed as argument name in case no name has been passed.

func WrapperTODO

func WrapperTODO(function any) Wrapper

Directories

Path Synopsis
cli module
cmd
htmlform module

Jump to

Keyboard shortcuts

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