core

package
v0.19.0 Latest Latest
Warning

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

Go to latest
Published: May 20, 2024 License: MIT Imports: 22 Imported by: 7

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 DirectiveOmitEmpty ¶ added in v0.19.0

type DirectiveOmitEmpty struct{}

DirectiveOmitEmpty is used with the DirectiveQuery, DirectiveForm, and DirectiveHeader to indicate that the field should be omitted when the value is empty. It does not have any affect when used by itself

func (*DirectiveOmitEmpty) Decode ¶ added in v0.19.0

func (*DirectiveOmitEmpty) Encode ¶ added in v0.19.0

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