shape

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 6, 2025 License: MIT Imports: 28 Imported by: 0

README

shape

CI Go Reference Go Report Card

Type-safe validation, transformation, and JSON binding for Go.

Describe a struct once, then transform, validate, or decode JSON with the same definition. Invalid field configuration panics at construction; bad input returns errors.

Features

  • Struct tags or explicit Schemas — shape.BindJSON for DTOs; shape.New when rules belong in Go
  • Transform and validate stay separate — JSON always runs decode → transform → validate
  • Typed errors — stable issue codes and JSON paths; English / 简体中文 messages
  • Stdlib only at runtime — no third-party dependencies for the library itself
  • Optional shapevet — static checks for tags and explicit field names

Status

Release candidate. The public surface and behavioral contract are frozen in docs/API.md; after the first public tag, incompatible changes require a major version.

Install

go get github.com/rhevorn/shape

Requires Go 1.24 or newer.

Struct tags

For simple DTOs, put rules on the struct and bind with no Schema variable:

type CreateUserRequest struct {
	Name string `json:"name" shape:"trim,notempty,maxlength=50"`
	Age  int    `json:"age" shape:"min=18,max=120"`
}

var request CreateUserRequest
err := shape.BindJSON(&request, data)

BindJSON writes the target only after the full pipeline succeeds.

Explicit Schema

Field behavior written in Go with shape.New:

type User struct {
	Name string   `json:"name"`
	Age  int      `json:"age"`
	Tags []string `json:"tags"`
}

var userSchema = shape.New[User](
	shape.String("Name").Trim().NotEmpty().MaxLength(50),
	shape.Int("Age").Min(18).Max(120),
	shape.Slice("Tags", shape.String().Trim().NotEmpty()).NotEmpty().Unique(),
)

user, err := userSchema.ParseJSON([]byte(`{
	"name": " Pong ",
	"age": 20,
	"tags": [" go ", "shape"]
}`))
// user.Name == "Pong"

The same schema also supports Transform and Validate on typed values.

Scalars

Standalone string Specs work the same way without a struct:

name := shape.String().Trim().ToLower().NotEmpty()

out, err := name.Transform(" Pong ")
// out == "pong", err == nil

err = name.Validate(out)

Documentation

License

MIT

Documentation

Overview

Package shape defines typed transformation, validation, and JSON Schemas.

New defines an explicit Schema from typed field Specs. Struct compiles a cached Schema from struct tags. Schema itself is Transform + Validate only. StructSpec and TaggedSpec also implement JSONSchema for ParseJSON. Package-level ParseJSON works with any Schema; BindJSON is the tag-driven shortcut that needs no Schema variable and writes through a pointer.

Use the validate and transform subpackages when only one capability is needed.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrJSONTooLarge = errors.New("shape: JSON input too large")

ErrJSONTooLarge reports that JSON input exceeded JSONOptions.MaxBytes.

Functions

func BindJSON

func BindJSON[T any](target *T, source []byte, options ...JSONOptions) error

BindJSON derives the target's cached tagged struct Schema and atomically replaces *target only after decode, transform, and validation all succeed. No Schema variable is required; field behavior comes from shape tags.

Example
package main

import (
	"fmt"

	"github.com/rhevorn/shape"
)

func main() {
	type Request struct {
		Name string `json:"name" shape:"trim,notempty"`
	}

	var request Request
	err := shape.BindJSON(&request, []byte(`{"name":" Pong "}`))

	fmt.Println(request.Name, err)
}
Output:
Pong <nil>

func BindJSONContext

func BindJSONContext[T any](ctx context.Context, target *T, source []byte, options ...JSONOptions) error

BindJSONContext is the context-aware form of BindJSON.

func BindJSONReader

func BindJSONReader[T any](target *T, reader io.Reader, options ...JSONOptions) error

BindJSONReader derives the target's cached tagged struct Schema and atomically binds one JSON value from reader.

func BindJSONReaderContext

func BindJSONReaderContext[T any](ctx context.Context, target *T, reader io.Reader, options ...JSONOptions) error

BindJSONReaderContext is the context-aware reader form of BindJSON.

func ExportDocument

func ExportDocument[T any](schema Schema[T]) (map[string]any, error)

ExportDocument exports representable behavior as a JSON Schema object without a root $schema dialect declaration. Most users should call jsonschema.Export.

func ParseJSON

func ParseJSON[T any](schema Schema[T], source []byte, options ...JSONOptions) (T, error)

ParseJSON decodes, transforms, and validates one JSON value with schema. Use this for scalar or composite Schema roots. Prefer StructSpec/TaggedSpec methods when the Schema is already a named struct Schema.

func ParseJSONContext

func ParseJSONContext[T any](ctx context.Context, schema Schema[T], source []byte, options ...JSONOptions) (T, error)

ParseJSONContext is ParseJSON with cancellation and per-request locale.

func ParseJSONReader

func ParseJSONReader[T any](schema Schema[T], reader io.Reader, options ...JSONOptions) (T, error)

ParseJSONReader decodes, transforms, and validates one value from reader.

func ParseJSONReaderContext

func ParseJSONReaderContext[T any](ctx context.Context, schema Schema[T], reader io.Reader, options ...JSONOptions) (T, error)

ParseJSONReaderContext is the context-aware reader form of ParseJSON.

Types

type FieldSpec

type FieldSpec interface {
	// contains filtered or unexported methods
}

FieldSpec is an explicit field definition accepted by New. Its unexported method intentionally limits implementations to this package.

func Field

func Field[T any](name string, schema Schema[T]) FieldSpec

Field uses another Schema for a nested field.

type JSONOptions

type JSONOptions struct {
	DisallowUnknownFields bool
	MaxBytes              int64
}

JSONOptions controls the standard JSON decoding stage. MaxBytes zero means unlimited; a positive value rejects larger input with ErrJSONTooLarge.

type JSONSchema

type JSONSchema[T any] interface {
	Schema[T]

	ParseJSON([]byte, ...JSONOptions) (T, error)
	ParseJSONContext(context.Context, []byte, ...JSONOptions) (T, error)
	ParseJSONReader(io.Reader, ...JSONOptions) (T, error)
	ParseJSONReaderContext(context.Context, io.Reader, ...JSONOptions) (T, error)
}

JSONSchema is the struct Schema surface that owns ParseJSON. Scalar and composite Specs implement Schema only; use package-level ParseJSON* when a non-struct Schema is the JSON root. For tag-driven in-place bind, use package-level BindJSON* — it needs no Schema variable.

type MapKey

type MapKey interface {
	~string |
		~int | ~int8 | ~int16 | ~int32 | ~int64 |
		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
}

MapKey is the set of key types supported by Map. Named string and integer types are included through the underlying-type constraints.

type MapSpec

type MapSpec[K MapKey, V any] struct {
	// contains filtered or unexported fields
}

MapSpec defines behavior for a map and each key and value.

func Map

func Map[K MapKey, V any](name string, key Schema[K], value Schema[V]) MapSpec[K, V]

Map creates a map Schema that applies key and value in stable key order.

func (MapSpec[K, V]) Apply

func (f MapSpec[K, V]) Apply(values ...func(map[K]V) (map[K]V, error)) MapSpec[K, V]

func (MapSpec[K, V]) ApplyContext

func (f MapSpec[K, V]) ApplyContext(values ...func(context.Context, map[K]V) (map[K]V, error)) MapSpec[K, V]

func (MapSpec[K, V]) IfNull

func (f MapSpec[K, V]) IfNull(v map[K]V) MapSpec[K, V]

func (MapSpec[K, V]) Label

func (f MapSpec[K, V]) Label(label string) MapSpec[K, V]

func (MapSpec[K, V]) Len

func (f MapSpec[K, V]) Len(n int) MapSpec[K, V]

func (MapSpec[K, V]) Max

func (f MapSpec[K, V]) Max(n int) MapSpec[K, V]

func (MapSpec[K, V]) Min

func (f MapSpec[K, V]) Min(n int) MapSpec[K, V]

func (MapSpec[K, V]) NotEmpty

func (f MapSpec[K, V]) NotEmpty() MapSpec[K, V]

func (MapSpec[K, V]) NotNull

func (f MapSpec[K, V]) NotNull() MapSpec[K, V]

func (MapSpec[K, V]) Refine

func (f MapSpec[K, V]) Refine(values ...func(map[K]V) error) MapSpec[K, V]

func (MapSpec[K, V]) RefineContext

func (f MapSpec[K, V]) RefineContext(values ...func(context.Context, map[K]V) error) MapSpec[K, V]

func (MapSpec[K, V]) Transform

func (f MapSpec[K, V]) Transform(v map[K]V) (map[K]V, error)

func (MapSpec[K, V]) TransformContext

func (f MapSpec[K, V]) TransformContext(ctx context.Context, v map[K]V) (map[K]V, error)

func (MapSpec[K, V]) Validate

func (f MapSpec[K, V]) Validate(v map[K]V) error

func (MapSpec[K, V]) ValidateContext

func (f MapSpec[K, V]) ValidateContext(ctx context.Context, v map[K]V) error

func (MapSpec[K, V]) ValidateFirst

func (f MapSpec[K, V]) ValidateFirst(v map[K]V) error

func (MapSpec[K, V]) ValidateFirstContext

func (f MapSpec[K, V]) ValidateFirstContext(ctx context.Context, v map[K]V) error

type NumberSpec

type NumberSpec[N Numeric] struct {
	// contains filtered or unexported fields
}

NumberSpec defines transform and validation behavior for a numeric value.

func Duration

func Duration(name ...string) NumberSpec[types.Duration]

Duration creates a Schema for types.Duration.

func Float64

func Float64(name ...string) NumberSpec[float64]

Float64 creates a float64 Schema.

func Int

func Int(name ...string) NumberSpec[int]

Int creates an int Schema.

func Int64

func Int64(name ...string) NumberSpec[int64]

Int64 creates an int64 Schema.

func Number

func Number[N Numeric](name ...string) NumberSpec[N]

Number creates a numeric Schema, optionally named for use in New.

func (NumberSpec[N]) Apply

func (f NumberSpec[N]) Apply(values ...func(N) (N, error)) NumberSpec[N]

func (NumberSpec[N]) ApplyContext

func (f NumberSpec[N]) ApplyContext(values ...func(context.Context, N) (N, error)) NumberSpec[N]

func (NumberSpec[N]) Between

func (f NumberSpec[N]) Between(a, b N) NumberSpec[N]

func (NumberSpec[N]) Gt

func (f NumberSpec[N]) Gt(v N) NumberSpec[N]

func (NumberSpec[N]) Gte

func (f NumberSpec[N]) Gte(v N) NumberSpec[N]

func (NumberSpec[N]) IfZero

func (f NumberSpec[N]) IfZero(v N) NumberSpec[N]

func (NumberSpec[N]) Label

func (f NumberSpec[N]) Label(label string) NumberSpec[N]

func (NumberSpec[N]) Lt

func (f NumberSpec[N]) Lt(v N) NumberSpec[N]

func (NumberSpec[N]) Lte

func (f NumberSpec[N]) Lte(v N) NumberSpec[N]

func (NumberSpec[N]) Max

func (f NumberSpec[N]) Max(v N) NumberSpec[N]

func (NumberSpec[N]) Min

func (f NumberSpec[N]) Min(v N) NumberSpec[N]

func (NumberSpec[N]) Negative

func (f NumberSpec[N]) Negative() NumberSpec[N]

func (NumberSpec[N]) NonNegative

func (f NumberSpec[N]) NonNegative() NumberSpec[N]

func (NumberSpec[N]) OneOf

func (f NumberSpec[N]) OneOf(values ...N) NumberSpec[N]

func (NumberSpec[N]) Pointer

func (f NumberSpec[N]) Pointer() PointerSpec[N]

func (NumberSpec[N]) Positive

func (f NumberSpec[N]) Positive() NumberSpec[N]

func (NumberSpec[N]) Refine

func (f NumberSpec[N]) Refine(values ...func(N) error) NumberSpec[N]

func (NumberSpec[N]) RefineContext

func (f NumberSpec[N]) RefineContext(values ...func(context.Context, N) error) NumberSpec[N]

func (NumberSpec[N]) Slice

func (f NumberSpec[N]) Slice() SliceSpec[N]

func (NumberSpec[N]) Transform

func (f NumberSpec[N]) Transform(v N) (N, error)

func (NumberSpec[N]) TransformContext

func (f NumberSpec[N]) TransformContext(ctx context.Context, v N) (N, error)

func (NumberSpec[N]) Validate

func (f NumberSpec[N]) Validate(v N) error

func (NumberSpec[N]) ValidateContext

func (f NumberSpec[N]) ValidateContext(ctx context.Context, v N) error

func (NumberSpec[N]) ValidateFirst

func (f NumberSpec[N]) ValidateFirst(v N) error

func (NumberSpec[N]) ValidateFirstContext

func (f NumberSpec[N]) ValidateFirstContext(ctx context.Context, v N) error

type Numeric

type Numeric interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 |
		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 |
		~float32 | ~float64
}

Numeric is the set of scalar number types supported by Number.

type PointerSpec

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

PointerSpec defines behavior for a pointer and its non-nil inner value.

func Pointer

func Pointer[T any](name string, inner Schema[T]) PointerSpec[T]

Pointer creates a pointer Schema with inner behavior for non-nil values.

func (PointerSpec[T]) Apply

func (f PointerSpec[T]) Apply(values ...func(*T) (*T, error)) PointerSpec[T]

func (PointerSpec[T]) ApplyContext

func (f PointerSpec[T]) ApplyContext(values ...func(context.Context, *T) (*T, error)) PointerSpec[T]

func (PointerSpec[T]) IfNull

func (f PointerSpec[T]) IfNull(v *T) PointerSpec[T]

func (PointerSpec[T]) Label

func (f PointerSpec[T]) Label(label string) PointerSpec[T]

func (PointerSpec[T]) NotEmpty

func (f PointerSpec[T]) NotEmpty() PointerSpec[T]

func (PointerSpec[T]) NotNull

func (f PointerSpec[T]) NotNull() PointerSpec[T]

func (PointerSpec[T]) Refine

func (f PointerSpec[T]) Refine(values ...func(*T) error) PointerSpec[T]

func (PointerSpec[T]) RefineContext

func (f PointerSpec[T]) RefineContext(values ...func(context.Context, *T) error) PointerSpec[T]

func (PointerSpec[T]) Transform

func (f PointerSpec[T]) Transform(v *T) (*T, error)

func (PointerSpec[T]) TransformContext

func (f PointerSpec[T]) TransformContext(ctx context.Context, v *T) (*T, error)

func (PointerSpec[T]) Validate

func (f PointerSpec[T]) Validate(v *T) error

func (PointerSpec[T]) ValidateContext

func (f PointerSpec[T]) ValidateContext(ctx context.Context, v *T) error

func (PointerSpec[T]) ValidateFirst

func (f PointerSpec[T]) ValidateFirst(v *T) error

func (PointerSpec[T]) ValidateFirstContext

func (f PointerSpec[T]) ValidateFirstContext(ctx context.Context, v *T) error

type Schema

type Schema[T any] interface {
	Transform(T) (T, error)
	TransformContext(context.Context, T) (T, error)
	Validate(T) error
	ValidateContext(context.Context, T) error
	ValidateFirst(T) error
	ValidateFirstContext(context.Context, T) error
}

Schema describes transformation and validation for T. Transformation and validation remain independently callable. JSON decode lives on StructSpec/TaggedSpec (JSONSchema) and package-level ParseJSON*; tag-driven BindJSON* is package-level only.

type SliceSpec

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

SliceSpec defines behavior for a slice and each of its elements.

func Slice

func Slice[T any](name string, inner Schema[T]) SliceSpec[T]

Slice creates a slice Schema that applies inner to every element.

func (SliceSpec[T]) Apply

func (f SliceSpec[T]) Apply(values ...func([]T) ([]T, error)) SliceSpec[T]

func (SliceSpec[T]) ApplyContext

func (f SliceSpec[T]) ApplyContext(values ...func(context.Context, []T) ([]T, error)) SliceSpec[T]

func (SliceSpec[T]) IfNull

func (f SliceSpec[T]) IfNull(v []T) SliceSpec[T]

func (SliceSpec[T]) Label

func (f SliceSpec[T]) Label(label string) SliceSpec[T]

func (SliceSpec[T]) Len

func (f SliceSpec[T]) Len(n int) SliceSpec[T]

func (SliceSpec[T]) Max

func (f SliceSpec[T]) Max(n int) SliceSpec[T]

func (SliceSpec[T]) Min

func (f SliceSpec[T]) Min(n int) SliceSpec[T]

func (SliceSpec[T]) NotEmpty

func (f SliceSpec[T]) NotEmpty() SliceSpec[T]

func (SliceSpec[T]) NotNull

func (f SliceSpec[T]) NotNull() SliceSpec[T]

func (SliceSpec[T]) Refine

func (f SliceSpec[T]) Refine(values ...func([]T) error) SliceSpec[T]

func (SliceSpec[T]) RefineContext

func (f SliceSpec[T]) RefineContext(values ...func(context.Context, []T) error) SliceSpec[T]

func (SliceSpec[T]) Transform

func (f SliceSpec[T]) Transform(v []T) ([]T, error)

func (SliceSpec[T]) TransformContext

func (f SliceSpec[T]) TransformContext(ctx context.Context, v []T) ([]T, error)

func (SliceSpec[T]) Unique

func (f SliceSpec[T]) Unique() SliceSpec[T]

func (SliceSpec[T]) Validate

func (f SliceSpec[T]) Validate(v []T) error

func (SliceSpec[T]) ValidateContext

func (f SliceSpec[T]) ValidateContext(ctx context.Context, v []T) error

func (SliceSpec[T]) ValidateFirst

func (f SliceSpec[T]) ValidateFirst(v []T) error

func (SliceSpec[T]) ValidateFirstContext

func (f SliceSpec[T]) ValidateFirstContext(ctx context.Context, v []T) error

type StringSpec

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

StringSpec defines transform and validation behavior for a string value.

func String

func String(name ...string) StringSpec

String creates a string Schema, optionally named for use in New.

Example
package main

import (
	"fmt"

	"github.com/rhevorn/shape"
)

func main() {
	name := shape.String().Trim().ToLower().NotEmpty()
	out, err := name.Transform(" Pong ")

	fmt.Println(out, err)
	fmt.Println(name.Validate(out))
}
Output:
pong <nil>
<nil>

func (StringSpec) Apply

func (f StringSpec) Apply(values ...func(string) (string, error)) StringSpec

func (StringSpec) ApplyContext

func (f StringSpec) ApplyContext(values ...func(context.Context, string) (string, error)) StringSpec

func (StringSpec) Contains

func (f StringSpec) Contains(v string) StringSpec

func (StringSpec) Email

func (f StringSpec) Email() StringSpec

func (StringSpec) EndsWith

func (f StringSpec) EndsWith(v string) StringSpec

func (StringSpec) IP

func (f StringSpec) IP() StringSpec

func (StringSpec) IfZero

func (f StringSpec) IfZero(v string) StringSpec

func (StringSpec) LTrim

func (f StringSpec) LTrim(chars ...string) StringSpec

func (StringSpec) Label

func (f StringSpec) Label(label string) StringSpec

func (StringSpec) Len

func (f StringSpec) Len(n int) StringSpec

func (StringSpec) MaxLength

func (f StringSpec) MaxLength(n int) StringSpec

func (StringSpec) MinLength

func (f StringSpec) MinLength(n int) StringSpec

func (StringSpec) NotEmpty

func (f StringSpec) NotEmpty() StringSpec

func (StringSpec) OneOf

func (f StringSpec) OneOf(values ...string) StringSpec

func (StringSpec) Pattern

func (f StringSpec) Pattern(expr string) StringSpec

func (StringSpec) Pointer

func (f StringSpec) Pointer() PointerSpec[string]

func (StringSpec) RTrim

func (f StringSpec) RTrim(chars ...string) StringSpec

func (StringSpec) Refine

func (f StringSpec) Refine(values ...func(string) error) StringSpec

func (StringSpec) RefineContext

func (f StringSpec) RefineContext(values ...func(context.Context, string) error) StringSpec

func (StringSpec) Slice

func (f StringSpec) Slice() SliceSpec[string]

func (StringSpec) StartsWith

func (f StringSpec) StartsWith(v string) StringSpec

func (StringSpec) ToLower

func (f StringSpec) ToLower() StringSpec

func (StringSpec) ToUpper

func (f StringSpec) ToUpper() StringSpec

func (StringSpec) Transform

func (f StringSpec) Transform(v string) (string, error)

func (StringSpec) TransformContext

func (f StringSpec) TransformContext(ctx context.Context, v string) (string, error)

func (StringSpec) Trim

func (f StringSpec) Trim(chars ...string) StringSpec

func (StringSpec) URL

func (f StringSpec) URL() StringSpec

func (StringSpec) UUID

func (f StringSpec) UUID() StringSpec

func (StringSpec) Validate

func (f StringSpec) Validate(v string) error

func (StringSpec) ValidateContext

func (f StringSpec) ValidateContext(ctx context.Context, v string) error

func (StringSpec) ValidateFirst

func (f StringSpec) ValidateFirst(v string) error

func (StringSpec) ValidateFirstContext

func (f StringSpec) ValidateFirstContext(ctx context.Context, v string) error

type StructSpec

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

StructSpec is the immutable explicit struct Schema returned by New.

func New

func New[T any](fields ...FieldSpec) StructSpec[T]

New creates an explicit reusable Schema for an ordinary value struct. Fields not listed in fields pass through unchanged and are not validated. New does not inspect shape tags.

Example
package main

import (
	"fmt"

	"github.com/rhevorn/shape"
)

func main() {
	type User struct {
		Name string `json:"name"`
		Age  int    `json:"age"`
	}

	schema := shape.New[User](
		shape.String("Name").Trim().NotEmpty(),
		shape.Int("Age").Min(18),
	)
	user, err := schema.ParseJSON([]byte(`{"name":" Pong ","age":20}`))

	fmt.Println(user.Name, user.Age, err)
}
Output:
Pong 20 <nil>

func (StructSpec[T]) Apply

func (s StructSpec[T]) Apply(steps ...func(T) (T, error)) StructSpec[T]

Apply appends one or more whole-struct transforms after all field transforms.

func (StructSpec[T]) ApplyContext

func (s StructSpec[T]) ApplyContext(steps ...func(context.Context, T) (T, error)) StructSpec[T]

ApplyContext is the context-aware form of Apply.

func (StructSpec[T]) ParseJSON

func (s StructSpec[T]) ParseJSON(source []byte, options ...JSONOptions) (T, error)

ParseJSON decodes, transforms, and validates one JSON value.

func (StructSpec[T]) ParseJSONContext

func (s StructSpec[T]) ParseJSONContext(ctx context.Context, source []byte, options ...JSONOptions) (T, error)

ParseJSONContext decodes, transforms, and validates with ctx.

func (StructSpec[T]) ParseJSONReader

func (s StructSpec[T]) ParseJSONReader(reader io.Reader, options ...JSONOptions) (T, error)

ParseJSONReader reads, transforms, and validates one JSON value.

func (StructSpec[T]) ParseJSONReaderContext

func (s StructSpec[T]) ParseJSONReaderContext(ctx context.Context, reader io.Reader, options ...JSONOptions) (T, error)

ParseJSONReaderContext is the context-aware reader form of ParseJSON.

func (StructSpec[T]) Refine

func (s StructSpec[T]) Refine(rules ...func(T) error) StructSpec[T]

Refine appends one or more whole-struct validation rules after all field rules.

func (StructSpec[T]) RefineContext

func (s StructSpec[T]) RefineContext(rules ...func(context.Context, T) error) StructSpec[T]

RefineContext is the context-aware form of Refine.

func (StructSpec[T]) Transform

func (s StructSpec[T]) Transform(value T) (T, error)

Transform applies field and whole-struct transforms without validation.

func (StructSpec[T]) TransformContext

func (s StructSpec[T]) TransformContext(ctx context.Context, value T) (T, error)

TransformContext applies transforms and observes context cancellation.

func (StructSpec[T]) Validate

func (s StructSpec[T]) Validate(value T) error

Validate collects validation issues without transforming value.

func (StructSpec[T]) ValidateContext

func (s StructSpec[T]) ValidateContext(ctx context.Context, value T) error

ValidateContext collects issues and observes context cancellation.

func (StructSpec[T]) ValidateFirst

func (s StructSpec[T]) ValidateFirst(value T) error

ValidateFirst stops after the first issue.

func (StructSpec[T]) ValidateFirstContext

func (s StructSpec[T]) ValidateFirstContext(ctx context.Context, value T) error

ValidateFirstContext stops after the first issue and observes cancellation.

type TaggedSpec

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

TaggedSpec is the immutable tagged struct Schema returned by Struct. Apply and Refine add whole-struct behavior after the compiled field behavior.

func Struct

func Struct[T any]() TaggedSpec[T]

Struct derives and caches a Schema for an ordinary value struct from its json and shape tags. Invalid program configuration panics during construction.

Example
package main

import (
	"fmt"

	"github.com/rhevorn/shape"
)

func main() {
	type Request struct {
		Name string `json:"name" shape:"trim,notempty"`
	}

	schema := shape.Struct[Request]()
	request, err := schema.ParseJSON([]byte(`{"name":" Pong "}`))

	fmt.Println(request.Name, err)
}
Output:
Pong <nil>

func (TaggedSpec[T]) Apply

func (s TaggedSpec[T]) Apply(steps ...func(T) (T, error)) TaggedSpec[T]

func (TaggedSpec[T]) ApplyContext

func (s TaggedSpec[T]) ApplyContext(steps ...func(context.Context, T) (T, error)) TaggedSpec[T]

func (TaggedSpec[T]) ParseJSON

func (s TaggedSpec[T]) ParseJSON(source []byte, options ...JSONOptions) (T, error)

ParseJSON decodes, transforms, and validates one JSON value.

func (TaggedSpec[T]) ParseJSONContext

func (s TaggedSpec[T]) ParseJSONContext(ctx context.Context, source []byte, options ...JSONOptions) (T, error)

ParseJSONContext decodes, transforms, and validates with ctx.

func (TaggedSpec[T]) ParseJSONReader

func (s TaggedSpec[T]) ParseJSONReader(reader io.Reader, options ...JSONOptions) (T, error)

ParseJSONReader reads, transforms, and validates one JSON value.

func (TaggedSpec[T]) ParseJSONReaderContext

func (s TaggedSpec[T]) ParseJSONReaderContext(ctx context.Context, reader io.Reader, options ...JSONOptions) (T, error)

ParseJSONReaderContext is the context-aware reader form of ParseJSON.

func (TaggedSpec[T]) Refine

func (s TaggedSpec[T]) Refine(rules ...func(T) error) TaggedSpec[T]

func (TaggedSpec[T]) RefineContext

func (s TaggedSpec[T]) RefineContext(rules ...func(context.Context, T) error) TaggedSpec[T]

func (TaggedSpec[T]) Transform

func (s TaggedSpec[T]) Transform(value T) (T, error)

Transform applies tag and whole-struct transforms without validation.

func (TaggedSpec[T]) TransformContext

func (s TaggedSpec[T]) TransformContext(ctx context.Context, value T) (T, error)

TransformContext applies transforms and observes context cancellation.

func (TaggedSpec[T]) Validate

func (s TaggedSpec[T]) Validate(value T) error

Validate collects validation issues without transforming value.

func (TaggedSpec[T]) ValidateContext

func (s TaggedSpec[T]) ValidateContext(ctx context.Context, value T) error

ValidateContext collects issues and observes context cancellation.

func (TaggedSpec[T]) ValidateFirst

func (s TaggedSpec[T]) ValidateFirst(value T) error

ValidateFirst stops after the first issue.

func (TaggedSpec[T]) ValidateFirstContext

func (s TaggedSpec[T]) ValidateFirstContext(ctx context.Context, value T) error

ValidateFirstContext stops after the first issue and observes cancellation.

type TransformError

type TransformError struct {
	Path validate.Path
	Err  error
}

TransformError reports the struct field or collection element whose tag transform failed. Unwrap returns the original transform error.

func (*TransformError) Error

func (e *TransformError) Error() string

Error formats the failed path and underlying error.

func (*TransformError) Unwrap

func (e *TransformError) Unwrap() error

Unwrap returns the underlying transform error.

type UnsupportedSchemaError

type UnsupportedSchemaError struct{ Feature string }

UnsupportedSchemaError reports processing that JSON Schema cannot represent without changing Shape's runtime behavior.

func (*UnsupportedSchemaError) Error

func (e *UnsupportedSchemaError) Error() string

Error identifies the behavior that cannot be represented.

type ValueSpec

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

ValueSpec defines transform and validation behavior for a value of any type.

func Bool

func Bool(name ...string) ValueSpec[bool]

Bool creates a bool Schema.

func Time

func Time(name ...string) ValueSpec[time.Time]

Time creates a time.Time Schema.

func Value

func Value[T any](name ...string) ValueSpec[T]

Value creates a Schema for any type. Omit name when using it as a Pointer, Slice, or Map element Schema.

func (ValueSpec[T]) Apply

func (f ValueSpec[T]) Apply(values ...func(T) (T, error)) ValueSpec[T]

func (ValueSpec[T]) ApplyContext

func (f ValueSpec[T]) ApplyContext(values ...func(context.Context, T) (T, error)) ValueSpec[T]

func (ValueSpec[T]) IfZero

func (f ValueSpec[T]) IfZero(v T) ValueSpec[T]

func (ValueSpec[T]) Label

func (f ValueSpec[T]) Label(label string) ValueSpec[T]

func (ValueSpec[T]) Pointer

func (f ValueSpec[T]) Pointer() PointerSpec[T]

func (ValueSpec[T]) Refine

func (f ValueSpec[T]) Refine(values ...func(T) error) ValueSpec[T]

func (ValueSpec[T]) RefineContext

func (f ValueSpec[T]) RefineContext(values ...func(context.Context, T) error) ValueSpec[T]

func (ValueSpec[T]) Slice

func (f ValueSpec[T]) Slice() SliceSpec[T]

func (ValueSpec[T]) Transform

func (f ValueSpec[T]) Transform(v T) (T, error)

func (ValueSpec[T]) TransformContext

func (f ValueSpec[T]) TransformContext(ctx context.Context, v T) (T, error)

func (ValueSpec[T]) Validate

func (f ValueSpec[T]) Validate(v T) error

func (ValueSpec[T]) ValidateContext

func (f ValueSpec[T]) ValidateContext(ctx context.Context, v T) error

func (ValueSpec[T]) ValidateFirst

func (f ValueSpec[T]) ValidateFirst(v T) error

func (ValueSpec[T]) ValidateFirstContext

func (f ValueSpec[T]) ValidateFirstContext(ctx context.Context, v T) error

Directories

Path Synopsis
examples
config command
http command
shape/errors command
shape/explicit command
shape/export command
shape/json command
shape/tags command
shape/types command
transform command
validate command
internal
maporder
Package maporder provides the deterministic map traversal order shared by Shape's tagged, validation, and transformation paths.
Package maporder provides the deterministic map traversal order shared by Shape's tagged, validation, and transformation paths.
reflectclone
Package reflectclone holds the deep-copy policy shared by the root and transform packages.
Package reflectclone holds the deep-copy policy shared by the root and transform packages.
spec
Package spec contains immutable construction descriptors shared by shape's packages.
Package spec contains immutable construction descriptors shared by shape's packages.
stringrule
Package stringrule contains string predicates shared by fluent validators and compiled struct tags.
Package stringrule contains string predicates shared by fluent validators and compiled struct tags.
taglang
Package taglang parses Shape's shared struct-tag language.
Package taglang parses Shape's shared struct-tag language.
transformpath
Package transformpath carries collection paths across the public transform package boundary without exposing an intermediate error type to users.
Package transformpath carries collection paths across the public transform package boundary without exposing an intermediate error type to users.
validationmsg
Package validationmsg owns built-in validation message templates shared by explicit validators and tag-driven schemas.
Package validationmsg owns built-in validation message templates shared by explicit validators and tag-driven schemas.
Package jsonschema exports shape schemas as JSON Schema Draft 2020-12.
Package jsonschema exports shape schemas as JSON Schema Draft 2020-12.
Package openapi adapts shape schemas for OpenAPI 3.1 documents.
Package openapi adapts shape schemas for OpenAPI 3.1 documents.
Package transform defines immutable, strongly typed T-to-T transformations.
Package transform defines immutable, strongly typed T-to-T transformations.
Package types provides data types with explicit JSON representations.
Package types provides data types with explicit JSON representations.
Package validate defines immutable, strongly typed validators with structured errors, stable paths, aggregate and fail-fast calls, and typed localization.
Package validate defines immutable, strongly typed validators with structured errors, stable paths, aggregate and fail-fast calls, and typed localization.

Jump to

Keyboard shortcuts

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