Documentation
¶
Overview ¶
Package litval decodes Go composite literals into live Go values — the "configuration as Go code" pattern of code generators, where a marker variable of a known config struct type is read statically from source that does not have to compile.
FindVars locates the marker variables by resolved type identity (robust to renamed imports, dot-imports, and aliases), and Decoder fills a compiled Go value from the initializer: scalar fields accept any constant expression the enclosing file can evaluate (named constants, arithmetic, conversions — same or other packages), composites recurse through structs, slices, arrays, constant-keyed maps, and pointers, and interface-typed fields are delegated to a caller-supplied hook. litval is a decoder, not an interpreter: it never executes user code.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrDecode = errors.New("cannot decode literal")
ErrDecode is wrapped by every structural decode failure — an expression shape, literal form, or target the decoder does not accept. Constant-evaluation failures propagate the core library's error chain instead, so errors.Is against typeparser sentinels keeps working.
Functions ¶
func DecodeAs ¶
func DecodeAs[T any](d *Decoder, vd *typeparser.VarDecl) (*T, error)
DecodeAs is the generic convenience over Decode: it allocates a T, decodes vd's initializer into it, and returns it.
func FindVars ¶
func FindVars(pkg *typeparser.Package, typePkgPath, typeName string) []*typeparser.VarDecl
FindVars returns, in source order, the package-level variables whose declared or inferred type — after following aliases and unwrapping pointers and slices — is the named type (typePkgPath, typeName). Matching is by resolved identity, so renamed imports and dot-imports match by construction. Variables whose type cannot be resolved are skipped.
Types ¶
type Context ¶
type Context struct {
Var *typeparser.VarDecl
File *typeparser.File
}
Context is the resolution context passed to a Decoder's Hook: the variable being decoded and its file, which is the import scope of every expression (and, via File.Position, the way to position ast nodes).
type Decoder ¶
type Decoder struct {
// Hook, when set, is consulted first for every value expression. It
// handles what the generic decoder cannot — interface-typed fields,
// such as adv-pg's Table.Model — or overrides what it could.
// Returning handled == true consumes the expression; a non-nil error
// fails the decode and is prefixed with the expression's position.
Hook func(ctx *Context, target reflect.Value, e ast.Expr) (handled bool, err error)
// Strict verifies every struct literal written with a named type
// (identifier or selector; aliases are followed) against the reflect
// target: same package path, same type name. This catches version
// skew between the generator binary's compiled config types and the
// user module's source.
Strict bool
}
Decoder decodes composite-literal initializers into Go values. The zero value is ready to use. A Decoder holds no decode state and is safe for concurrent use when its Hook is.
func (*Decoder) Decode ¶
func (d *Decoder) Decode(vd *typeparser.VarDecl, out any) error
Decode decodes vd's initializer into out, which must be a non-nil pointer. The initializer is decoded against out's element type — a &T{…} initializer is unwrapped for a struct target — and every error carries a source position.
type Validator ¶
type Validator interface{ Validate() error }
Validator is implemented by config types that check their own invariants. After filling a struct (nested ones included) whose address implements it, the decoder invokes Validate and fails the decode with the literal's position on a non-nil result.