core

package
v0.18.0 Latest Latest
Warning

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

Go to latest
Published: Apr 20, 2024 License: MIT Imports: 22 Imported by: 1

Documentation

Index

Constants

View Source
const (
	// CtxRequest is the key to get the HTTP request value (of *http.Request)
	// from DirectiveRuntime.Context. The HTTP request value is injected by
	// httpin to the context of DirectiveRuntime before executing the directive.
	// See Core.Decode() for more details.
	CtxRequest contextKey = iota

	CtxRequestBuilder

	// CtxCustomCoder is the key to get the custom decoder for a field from
	// Resolver.Context. Which is specified by the "decoder" directive.
	// During resolver building phase, the "decoder" directive will be removed
	// from the resolver, and the targeted decoder by name will be put into
	// Resolver.Context with this key. e.g.
	//
	//    type GreetInput struct {
	//        Message string `httpin:"decoder=custom"`
	//    }
	// For the above example, the decoder named "custom" will be put into the
	// resolver of Message field with this key.
	CtxCustomCoder

	// CtxFieldSet is used by executors to tell whether a field has been set. When
	// multiple executors were applied to a field, if the field value were set
	// by a former executor, the latter executors MAY skip running by consulting
	// this context value.
	CtxFieldSet
)

Variables

View Source
var (
	ErrUnregisteredDirective = errors.New("unregistered directive")
	ErrUnregisteredCoder     = errors.New("unregistered coder")
	ErrTypeMismatch          = internal.ErrTypeMismatch
)
View Source
var ErrUnknownBodyFormat = errors.New("unknown body format")

ErrUnknownBodyFormat is returned when a serializer for the specified body format has not been specified.

View Source
var ErrUnsupportedType = owl.ErrUnsupportedType

Functions

func EnableNestedDirectives

func EnableNestedDirectives(on bool)

EnableNestedDirectives sets the global flag to enable nested directives. Nested directives are disabled by default.

func IsPatchField

func IsPatchField(t reflect.Type) bool

func RegisterBodyFormat

func RegisterBodyFormat(format string, body BodySerializer, force ...bool)

RegisterBodyFormat registers a new data formatter for the body request, which has the BodyEncoderDecoder interface implemented. Panics on taken name, empty name or nil decoder. Pass parameter force (true) to ignore the name conflict.

The BodyEncoderDecoder is used by the body directive to decode and encode the data in the given format (body format).

It is also useful when you want to override the default registered BodyEncoderDecoder. For example, the default JSON decoder is borrowed from encoding/json. You can replace it with your own implementation, e.g. json-iterator/go. For example:

func init() {
    RegisterBodyFormat("json", &myJSONBody{}, true) // force register, replace the old one
    RegisterBodyFormat("yaml", &myYAMLBody{}) // register a new body format "yaml"
}

func RegisterCoder

func RegisterCoder[T any](adapt func(*T) (Stringable, error))

RegisterCoder registers a custom coder for the given type T. When a field of type T is encountered, this coder will be used to convert the value to a Stringable, which will be used to convert the value from/to string.

NOTE: this function is designed to override the default Stringable adaptors that are registered by this package. For example, if you want to override the defualt behaviour of converting a bool value from/to string, you can do this:

func init() {
	core.RegisterCoder[bool](func(b *bool) (core.Stringable, error) {
		return (*YesNo)(b), nil
	})
}

type YesNo bool

func (yn YesNo) String() string {
	if yn {
		return "yes"
	}
	return "no"
}

func (yn *YesNo) FromString(s string) error {
	switch s {
	case "yes":
		*yn = true
	case "no":
		*yn = false
	default:
		return fmt.Errorf("invalid YesNo value: %q", s)
	}
	return nil
}

func RegisterDirective

func RegisterDirective(name string, executor DirectiveExecutor, force ...bool)

RegisterDirective registers a DirectiveExecutor with the given directive name. The directive should be able to both extract the value from the HTTP request and build the HTTP request from the value. The Decode API is used to decode data from the HTTP request to a field of the input struct, and Encode API is used to encode the field of the input struct to the HTTP request.

Will panic if the name were taken or given executor is nil. Pass parameter force (true) to ignore the name conflict.

func RegisterErrorHandler

func RegisterErrorHandler(handler ErrorHandler)

RegisterErrorHandler replaces the default error handler with the given custom error handler. The default error handler will be used in the http.Handler that decoreated by the middleware created by NewInput().

func RegisterFileCoder

func RegisterFileCoder[T Fileable]() error

RegisterFileCoder registers the given type T as a file type. T must implement the Fileable interface. Remember if you don't register the type explicitly, it won't be recognized as a file type.

func RegisterNamedCoder

func RegisterNamedCoder[T any](name string, adapt func(*T) (Stringable, error))

RegisterNamedCoder works similar to RegisterCoder, except that it binds the coder to a name. This is useful when you only want to override the types in a specific struct field. You will be using the "coder" or "decoder" directive to specify the name of the coder to use. For example:

type MyStruct struct {
	Bool bool // use default bool coder
	YesNo bool `in:"coder=yesno"` // use YesNo coder
}

func init() {
	core.RegisterNamedCoder[bool]("yesno", func(b *bool) (core.Stringable, error) {
		return (*YesNo)(b), nil
	})
}

type YesNo bool

func (yn YesNo) String() string {
	if yn {
		return "yes"
	}
	return "no"
}

func (yn *YesNo) FromString(s string) error {
	switch s {
	case "yes":
		*yn = true
	case "no":
		*yn = false
	default:
		return fmt.Errorf("invalid YesNo value: %q", s)
	}
	return nil
}

Types

type AnyStringableAdaptor

type AnyStringableAdaptor = internal.AnyStringableAdaptor

type BodySerializer

type BodySerializer interface {
	// Decode decodes the request body into the specified object.
	Decode(src io.Reader, dst any) error
	// Encode encodes the specified object into a reader for the request body.
	Encode(src any) (io.Reader, error)
}

BodySerializer is the interface for encoding and decoding the request body. Common body formats are: json, xml, yaml, etc.

type Core

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

Core is the Core of httpin. It holds the resolver of a specific struct type. Who is responsible for decoding an HTTP request to an instance of such struct type.

func New

func New(inputStruct any, opts ...Option) (*Core, error)

New creates a new Core instance for the given intpuStruct. It will build a resolver for the inputStruct and apply the given options to the Core instance. The Core instance is responsible for both:

  • decoding an HTTP request to an instance of the inputStruct;
  • encoding an instance of the inputStruct to an HTTP request.

func (*Core) Decode

func (c *Core) Decode(req *http.Request) (any, error)

Decode decodes an HTTP request to an instance of the input struct and returns its pointer. For example:

New(Input{}).Decode(req) -> *Input

func (*Core) DecodeTo added in v0.18.0

func (c *Core) DecodeTo(req *http.Request, value any) (err error)

DecodeTo decodes an HTTP request to the given value. The value must be a pointer to the struct instance of the type that the Core instance holds.

func (*Core) GetErrorHandler

func (c *Core) GetErrorHandler() ErrorHandler

GetErrorHandler returns the error handler of the core if set, or the global custom error handler.

func (*Core) NewRequest

func (c *Core) NewRequest(method string, url string, input any) (*http.Request, error)

NewRequest wraps NewRequestWithContext using context.Background(), see NewRequestWithContext.

func (*Core) NewRequestWithContext

func (c *Core) NewRequestWithContext(ctx context.Context, method string, url string, input any) (*http.Request, error)

NewRequestWithContext turns the given input struct into an HTTP request. Note that the Core instance is bound to a specific type of struct. Which means when the given input is not the type of the struct that the Core instance holds, error of type mismatch will be returned. In order to avoid this error, you can always use httpin.NewRequest() instead. Which will create a Core instance for you on demand. There's no performance penalty for doing so. Because there's a cache layer for all the Core instances.

type DirectiveBody

type DirectiveBody struct{}

DirectiveBody is the implementation of the "body" directive.

func (*DirectiveBody) Decode

func (db *DirectiveBody) Decode(rtm *DirectiveRuntime) error

func (*DirectiveBody) Encode

func (db *DirectiveBody) Encode(rtm *DirectiveRuntime) error

type DirectiveDefault

type DirectiveDefault struct{}

func (*DirectiveDefault) Decode

func (*DirectiveDefault) Decode(rtm *DirectiveRuntime) error

func (*DirectiveDefault) Encode

func (*DirectiveDefault) Encode(rtm *DirectiveRuntime) error

type DirectiveExecutor

type DirectiveExecutor interface {
	// Encode encodes the field of the input struct to the HTTP request.
	Encode(*DirectiveRuntime) error

	// Decode decodes the field of the input struct from the HTTP request.
	Decode(*DirectiveRuntime) error
}

type DirectiveHeader

type DirectiveHeader struct{}

func (*DirectiveHeader) Decode

func (*DirectiveHeader) Decode(rtm *DirectiveRuntime) error

Decode implements the "header" executor who extracts values from the HTTP headers.

func (*DirectiveHeader) Encode

func (*DirectiveHeader) Encode(rtm *DirectiveRuntime) error

type DirectiveNonzero

type DirectiveNonzero struct{}

DirectiveNonzero implements the "nonzero" executor who indicates that the field must not be a "zero value". In golang, the "zero value" means:

  • nil
  • false
  • 0
  • ""
  • etc.

Unlike the "required" executor, the "nonzero" executor checks the value of the field.

func (*DirectiveNonzero) Decode

func (*DirectiveNonzero) Decode(rtm *DirectiveRuntime) error

func (*DirectiveNonzero) Encode

func (*DirectiveNonzero) Encode(rtm *DirectiveRuntime) error

type DirectivePath

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

func NewDirectivePath

func NewDirectivePath(decodeFunc func(*DirectiveRuntime) error) *DirectivePath

func (*DirectivePath) Decode

func (dir *DirectivePath) Decode(rtm *DirectiveRuntime) error

func (*DirectivePath) Encode

func (*DirectivePath) Encode(rtm *DirectiveRuntime) error

Encode replaces the placeholders in URL path with the given value.

type DirectiveQuery

type DirectiveQuery struct{}

func (*DirectiveQuery) Decode

func (*DirectiveQuery) Decode(rtm *DirectiveRuntime) error

Decode implements the "query" executor who extracts values from the querystring of an HTTP request.

func (*DirectiveQuery) Encode

func (*DirectiveQuery) Encode(rtm *DirectiveRuntime) error

type DirectiveRequired

type DirectiveRequired struct{}

DirectiveRequired implements the "required" executor who indicates that the field must be set. If the field value were not set by former executors, errMissingField will be returned.

NOTE: the "required" executor does not check the value of the field, it only checks if the field is set. In realcases, it's used to require that the key is present in the input data, e.g. form, header, etc. But it allows the value to be empty.

func (*DirectiveRequired) Decode

func (*DirectiveRequired) Encode

type DirectiveRuntime

type DirectiveRuntime owl.DirectiveRuntime

DirectiveRuntime is the runtime of a directive execution. It wraps owl.DirectiveRuntime, providing some additional helper methods particular to httpin.

See owl.DirectiveRuntime for more details.

func (*DirectiveRuntime) GetCustomCoder

func (rtm *DirectiveRuntime) GetCustomCoder() *NamedAnyStringableAdaptor

func (*DirectiveRuntime) GetRequest

func (rtm *DirectiveRuntime) GetRequest() *http.Request

func (*DirectiveRuntime) GetRequestBuilder

func (rtm *DirectiveRuntime) GetRequestBuilder() *RequestBuilder

func (*DirectiveRuntime) IsFieldSet

func (rtm *DirectiveRuntime) IsFieldSet() bool

func (*DirectiveRuntime) MarkFieldSet

func (rtm *DirectiveRuntime) MarkFieldSet(value bool)

func (*DirectiveRuntime) SetValue

func (rtm *DirectiveRuntime) SetValue(value any) error

type DirectvieForm

type DirectvieForm struct{}

func (*DirectvieForm) Decode

func (*DirectvieForm) Decode(rtm *DirectiveRuntime) error

Decode implements the "form" executor who extracts values from the forms of an HTTP request.

func (*DirectvieForm) Encode

func (*DirectvieForm) Encode(rtm *DirectiveRuntime) error

Encode implements the encoder/request builder for "form" directive. It builds the form values of an HTTP request, including:

  • form data
  • multipart form data (file upload)

type ErrorHandler

type ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error)

ErrorHandler is the type of custom error handler. The error handler is used by the http.Handler that created by NewInput() to handle errors during decoding the HTTP request.

type File

type File struct {
	FileHeader
	// contains filtered or unexported fields
}

File is the builtin type of httpin to manupulate file uploads. On the server side, it is used to represent a file in a multipart/form-data request. On the client side, it is used to represent a file to be uploaded.

func UploadFile

func UploadFile(filename string) *File

UploadFile is a helper function to create a File instance from a file path. It is useful when you want to upload a file from the local file system.

func UploadStream

func UploadStream(contentReader io.ReadCloser) *File

UploadStream is a helper function to create a File instance from a io.Reader. It is useful when you want to upload a file from a stream.

func (*File) Filename

func (f *File) Filename() string

Filename returns the filename of the file. On the server side, it returns the filename of the file in the multipart/form-data request. On the client side, it returns the filename of the file to be uploaded.

func (*File) IsUpload

func (f *File) IsUpload() bool

IsUpload returns true when the File instance is created for an upload purpose. Typically, you should use UploadFilename or UploadReader to create a File instance for upload.

func (*File) MarshalFile

func (f *File) MarshalFile() (io.ReadCloser, error)

MarshalFile implements FileMarshaler.

func (*File) OpenReceiveStream

func (f *File) OpenReceiveStream() (multipart.File, error)

OpenReceiveStream returns a io.Reader for the file in the multipart/form-data request. Call this method on the server side to read the file content.

func (*File) OpenUploadStream

func (f *File) OpenUploadStream() (io.ReadCloser, error)

OpenUploadStream returns a io.ReadCloser for the file to be uploaded. Call this method on the client side for uploading a file.

func (*File) ReadAll

func (f *File) ReadAll() ([]byte, error)

func (*File) UnmarshalFile

func (f *File) UnmarshalFile(fh FileHeader) error

type FileHeader

type FileHeader interface {
	Filename() string
	Size() int64
	MIMEHeader() textproto.MIMEHeader
	Open() (multipart.File, error)
}

FileHeader is the interface that groups the methods of multipart.FileHeader.

type FileMarshaler

type FileMarshaler interface {
	Filename() string
	MarshalFile() (io.ReadCloser, error)
}

type FileSlicable

type FileSlicable interface {
	ToFileSlice() ([]FileMarshaler, error)
	FromFileSlice([]FileHeader) error
}

func NewFileSlicable

func NewFileSlicable(rv reflect.Value) (FileSlicable, error)

type FileSlicablePatchFieldWrapper

type FileSlicablePatchFieldWrapper struct {
	Value reflect.Value // of patch.Field[T]
	// contains filtered or unexported fields
}

func NewFileSlicablePatchFieldWrapper

func NewFileSlicablePatchFieldWrapper(rv reflect.Value) (*FileSlicablePatchFieldWrapper, error)

func (*FileSlicablePatchFieldWrapper) FromFileSlice

func (w *FileSlicablePatchFieldWrapper) FromFileSlice(fhs []FileHeader) error

func (*FileSlicablePatchFieldWrapper) ToFileSlice

func (w *FileSlicablePatchFieldWrapper) ToFileSlice() ([]FileMarshaler, error)

type FileSlicableSingleFileableWrapper

type FileSlicableSingleFileableWrapper struct{ Fileable }

func NewFileSlicableSingleFileableWrapper

func NewFileSlicableSingleFileableWrapper(rv reflect.Value) (*FileSlicableSingleFileableWrapper, error)

func (*FileSlicableSingleFileableWrapper) FromFileSlice

func (w *FileSlicableSingleFileableWrapper) FromFileSlice(files []FileHeader) error

func (*FileSlicableSingleFileableWrapper) ToFileSlice

type FileUnmarshaler

type FileUnmarshaler interface {
	UnmarshalFile(FileHeader) error
}

type Fileable

type Fileable interface {
	FileMarshaler
	FileUnmarshaler
}

func NewFileable

func NewFileable(rv reflect.Value) (Fileable, error)

type FileablePatchFieldWrapper

type FileablePatchFieldWrapper struct {
	Value reflect.Value // of patch.Field[T]
	// contains filtered or unexported fields
}

func NewFileablePatchFieldWrapper

func NewFileablePatchFieldWrapper(rv reflect.Value) (*FileablePatchFieldWrapper, error)

func (*FileablePatchFieldWrapper) Filename

func (w *FileablePatchFieldWrapper) Filename() string

func (*FileablePatchFieldWrapper) MarshalFile

func (w *FileablePatchFieldWrapper) MarshalFile() (io.ReadCloser, error)

func (*FileablePatchFieldWrapper) UnmarshalFile

func (w *FileablePatchFieldWrapper) UnmarshalFile(fh FileHeader) error

type FileableSliceWrapper

type FileableSliceWrapper struct {
	Value reflect.Value
}

func NewFileableSliceWrapper

func NewFileableSliceWrapper(rv reflect.Value) (*FileableSliceWrapper, error)

func (*FileableSliceWrapper) FromFileSlice

func (w *FileableSliceWrapper) FromFileSlice(fhs []FileHeader) error

func (*FileableSliceWrapper) ToFileSlice

func (w *FileableSliceWrapper) ToFileSlice() ([]FileMarshaler, error)

type FormEncoder

type FormEncoder struct {
	Setter func(key string, value []string) // form value setter
}

func (*FormEncoder) Execute

func (e *FormEncoder) Execute(rtm *DirectiveRuntime) error

type FormExtractor

type FormExtractor struct {
	Runtime *DirectiveRuntime
	multipart.Form
	KeyNormalizer func(string) string
}

func (*FormExtractor) Extract

func (e *FormExtractor) Extract(keys ...string) error

type HybridCoder

type HybridCoder struct {
	internal.StringMarshaler
	internal.StringUnmarshaler
}

func (*HybridCoder) FromString

func (c *HybridCoder) FromString(s string) error

func (*HybridCoder) ToString

func (c *HybridCoder) ToString() (string, error)

type InvalidFieldError

type InvalidFieldError struct {

	// Field is the name of the field.
	Field string `json:"field"`

	// Source is the directive which causes the error.
	// e.g. form, header, required, etc.
	Directive string `json:"directive"`

	// Key is the key to get the input data from the source.
	Key string `json:"key"`

	// Value is the input data.
	Value any `json:"value"`

	// ErrorMessage is the string representation of `internalError`.
	ErrorMessage string `json:"error"`
	// contains filtered or unexported fields
}

func NewInvalidFieldError

func NewInvalidFieldError(err error) *InvalidFieldError

func (*InvalidFieldError) Error

func (e *InvalidFieldError) Error() string

func (*InvalidFieldError) Unwrap

func (e *InvalidFieldError) Unwrap() error

type JSONBody

type JSONBody struct{}

func (*JSONBody) Decode

func (de *JSONBody) Decode(src io.Reader, dst any) error

func (*JSONBody) Encode

func (en *JSONBody) Encode(src any) (io.Reader, error)

type MultiInvalidFieldError

type MultiInvalidFieldError []*InvalidFieldError

func (MultiInvalidFieldError) Error

func (me MultiInvalidFieldError) Error() string

func (MultiInvalidFieldError) Unwrap

func (me MultiInvalidFieldError) Unwrap() []error

type NamedAnyStringableAdaptor

type NamedAnyStringableAdaptor struct {
	Name     string
	BaseType reflect.Type
	Adapt    AnyStringableAdaptor
}

type Option

type Option func(*Core) error

func WithErrorHandler

func WithErrorHandler(custom ErrorHandler) Option

WithErrorHandler overrides the default error handler.

func WithMaxMemory

func WithMaxMemory(maxMemory int64) Option

WithMaxMemory overrides the default maximum memory size (32MB) when reading the request body. See https://pkg.go.dev/net/http#Request.ParseMultipartForm for more details.

func WithNestedDirectivesEnabled

func WithNestedDirectivesEnabled(enable bool) Option

WithNestedDirectivesEnabled enables/disables nested directives.

type RequestBuilder

type RequestBuilder struct {
	Query      url.Values
	Form       url.Values
	Attachment map[string][]FileMarshaler
	Header     http.Header
	Cookie     []*http.Cookie
	Path       map[string]string // placeholder: value
	BodyType   string            // json, xml, etc.
	Body       io.ReadCloser
	// contains filtered or unexported fields
}

func NewRequestBuilder added in v0.15.1

func NewRequestBuilder(ctx context.Context) *RequestBuilder

func (*RequestBuilder) Populate

func (rb *RequestBuilder) Populate(req *http.Request) error

func (*RequestBuilder) SetAttachment

func (rb *RequestBuilder) SetAttachment(key string, files []FileMarshaler)

func (*RequestBuilder) SetBody

func (rb *RequestBuilder) SetBody(bodyType string, bodyReader io.ReadCloser)

func (*RequestBuilder) SetForm

func (rb *RequestBuilder) SetForm(key string, value []string)

func (*RequestBuilder) SetHeader

func (rb *RequestBuilder) SetHeader(key string, value []string)

func (*RequestBuilder) SetPath

func (rb *RequestBuilder) SetPath(key string, value []string)

func (*RequestBuilder) SetQuery

func (rb *RequestBuilder) SetQuery(key string, value []string)

type StringSlicable

type StringSlicable interface {
	ToStringSlice() ([]string, error)
	FromStringSlice([]string) error
}

func NewStringSlicable

func NewStringSlicable(rv reflect.Value, adapt AnyStringableAdaptor) (StringSlicable, error)

type StringSlicablePatchFieldWrapper

type StringSlicablePatchFieldWrapper struct {
	Value reflect.Value // of patch.Field[T]
	// contains filtered or unexported fields
}

StringSlicablePatchFieldWrapper wraps a patch.Field[T] to implement StringSlicable. The wrapped reflect.Value must be a patch.Field[T].

It works like a proxy. It delegates the ToStringSlice and FromStringSlice calls to the internal StringSlicable.

func NewStringSlicablePatchFieldWrapper

func NewStringSlicablePatchFieldWrapper(rv reflect.Value, adapt AnyStringableAdaptor) (*StringSlicablePatchFieldWrapper, error)

NewStringSlicablePatchFieldWrapper creates a StringSlicablePatchFieldWrapper from rv. Returns error when patch.Field.Value is not a StringSlicable.

func (*StringSlicablePatchFieldWrapper) FromStringSlice

func (w *StringSlicablePatchFieldWrapper) FromStringSlice(values []string) error

func (*StringSlicablePatchFieldWrapper) ToStringSlice

func (w *StringSlicablePatchFieldWrapper) ToStringSlice() ([]string, error)

type StringSlicableSingleStringableWrapper

type StringSlicableSingleStringableWrapper struct{ Stringable }

StringSlicableSingleStringableWrapper wraps a reflect.Value to implement StringSlicable. The wrapped reflect.Value must be a Stringable.

func (*StringSlicableSingleStringableWrapper) FromStringSlice

func (w *StringSlicableSingleStringableWrapper) FromStringSlice(values []string) error

func (*StringSlicableSingleStringableWrapper) ToStringSlice

func (w *StringSlicableSingleStringableWrapper) ToStringSlice() ([]string, error)

type Stringable

type Stringable = internal.Stringable

func NewStringable

func NewStringable(rv reflect.Value, adapt AnyStringableAdaptor) (stringable Stringable, err error)

type StringablePatchFieldWrapper

type StringablePatchFieldWrapper struct {
	Value reflect.Value // of patch.Field[T]
	// contains filtered or unexported fields
}

func NewStringablePatchFieldWrapper

func NewStringablePatchFieldWrapper(rv reflect.Value, adapt AnyStringableAdaptor) (*StringablePatchFieldWrapper, error)

func (*StringablePatchFieldWrapper) FromString

func (w *StringablePatchFieldWrapper) FromString(s string) error

FromString sets the value of the wrapped patch.Field[T] from the given string. It returns an error if the given string is not valid. And leaves the original value of both Value and Valid unchanged. On the other hand, if no error occurs, it sets Valid to true.

func (*StringablePatchFieldWrapper) ToString

func (w *StringablePatchFieldWrapper) ToString() (string, error)

type StringableSlice

type StringableSlice []Stringable

func (StringableSlice) FromStringSlice

func (sa StringableSlice) FromStringSlice(values []string) error

func (StringableSlice) ToStringSlice

func (sa StringableSlice) ToStringSlice() ([]string, error)

type StringableSliceWrapper

type StringableSliceWrapper struct {
	Value reflect.Value
	Adapt AnyStringableAdaptor
}

StringableSliceWrapper wraps a reflect.Value to implement StringSlicable. The wrapped reflect.Value must be a slice of Stringable.

func NewStringableSliceWrapper

func NewStringableSliceWrapper(rv reflect.Value, adapt AnyStringableAdaptor) (*StringableSliceWrapper, error)

NewStringableSliceWrapper creates a StringableSliceWrapper from rv. Returns error when rv is not a slice of Stringable or cannot get address of rv.

func (*StringableSliceWrapper) FromStringSlice

func (w *StringableSliceWrapper) FromStringSlice(ss []string) error

func (*StringableSliceWrapper) ToStringSlice

func (w *StringableSliceWrapper) ToStringSlice() ([]string, error)

type TypeKind

type TypeKind int
const (
	TypeKindT           TypeKind = iota // T
	TypeKindTSlice                      // []T
	TypeKindPatchT                      // patch.Field[T]
	TypeKindPatchTSlice                 // patch.Field[[]T]
)

func BaseTypeOf

func BaseTypeOf(valueType reflect.Type) (reflect.Type, TypeKind)

BaseTypeOf returns the base type of the given type its kind. The kind represents how the given type is constructed from the base type.

  • T -> T, TypeKindT
  • []T -> T, TypeKindTSlice
  • patch.Field[T] -> T, TypeKindPatchT
  • patch.Field[[]T] -> T, TypeKindPatchTSlice

type XMLBody

type XMLBody struct{}

func (*XMLBody) Decode

func (de *XMLBody) Decode(src io.Reader, dst any) error

func (*XMLBody) Encode

func (en *XMLBody) Encode(src any) (io.Reader, error)

Jump to

Keyboard shortcuts

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