Documentation
¶
Overview ¶
Package morph is a Go code generator that generates code to map between structs and manipulate the form of functions.
All types should be considered read-only & immutable except where otherwise specified.
Need help? Ask on morph's GitHub issue tracker or check out the tutorials in the README. Also, paid commercial support and training is available via Open Source at Tawesoft.
Security Model ¶
WARNING: It is assumed that all inputs are trusted. DO NOT accept arbitrary input from untrusted sources under any circumstances, as this will parse and generate arbitrary code.
Index ¶
- Constants
- type ArgRewriter
- type Argument
- type BuiltinFieldExpression
- type Field
- type FieldExpression
- type FieldExpressionType
- type FieldMapper
- type Function
- type FunctionError
- type FunctionSignature
- func ParseFirstFunctionSignature(filename string, src any) (result FunctionSignature, err error)
- func ParseFunctionSignature(filename string, src any, name string) (result FunctionSignature, err error)
- func ParseMethodSignature(filename string, src any, Type string, name string) (result FunctionSignature, err error)
- type FunctionWrapper
- type Struct
- func (s Struct) Comparer(signature string) (Function, error)
- func (s Struct) Copier(signature string) (Function, error)
- func (s Struct) Copy() Struct
- func (s Struct) CustomBinaryFunction(operation string, signature string, other Struct) (Function, error)
- func (s Struct) CustomUnaryFunction(operation string, signature string) (Function, error)
- func (s Struct) Map(mappers ...StructMapper) Struct
- func (s Struct) MapFields(mappers ...FieldMapper) Struct
- func (s Struct) Orderer(signature string) (Function, error)
- func (s Struct) Signature() string
- func (s Struct) String() string
- func (s Struct) Truther(signature string) (Function, error)
- func (s Struct) Zeroer(signature string) (Function, error)
- type StructMapper
- type Variable
- type WrappedFunction
Examples ¶
Constants ¶
const ( FieldExpressionTypeVoid = "void" FieldExpressionTypeBool = "bool" FieldExpressionTypeValue = "value" )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ArgRewriter ¶
ArgRewriter either describes how an outer function rewrites its inputs before passing them to a wrapped inner function, or how an outer function rewrites the outputs of a wrapped inner function before returning them from the outer function.
It does this through capturing arguments into temporary variables, and formatting a new list of arguments or return values.
This is a low-level implementation for advanced use. The functions in morph/funcwrappers.go provide nicer APIs for many use cases.
A WrappedFunction uses two ArgRewriters in the following sequence, in pseudocode:
func outerfunc(args) (returns) { // step 0, a call to outerfunc inputs... = Input ArgRewriter captured args // step 1 results... = innerfunc(Input ArgWriter formats inputs) // step 2 outputs = Output ArgRewriter captured results // step 3 return Output ArgRewriter formats outputs // step 4 }
At each step, an ArgRewriter can retrieve the results of a previous step (and only the immediately previous step) by "$" token notation, accessing a named argument by "$name", and an argument by index by "$n" for some decimal n. At each step, a WrappedFunction uses an ArgRewriter to transform the result of the previous values.
In step 1, the results retrieved by "$" token notation are the input arguments to the outerfunc. In step 2, they are the captured arguments from step 1. In step 3, they are the return values from the innerfunc call. In step 4, they are the captured arguments from step 3.
Capture is a list of Field elements which describe how to temporarily store inputs to or outputs of invocations of the inner function. Only the Name, Type, and Value fields on each capture are used, and each is optional.
If a Name is given, a subsequent step can refer to the result by "$name", not just by index "$n".
The Value of the capture is a code expression of how it stores an input or output. In most cases, this will be simply correspond to the value of a matching input or output, unchanged. Here, inputs and named outputs can be referred to using "$" token notation by name e.g. "$name", or by index e.g. "$0". A value need not refer to any previous step, e.g. can be a literal like "2", or some function call like "time.Now()". For a single-valued result that is used only once, it may be better to do this in Formatter.
A capture with an empty string for a Value at position i in the capture slice captures the argument at position i in the previous step. Likewise, a capture with an empty Type at position i in the capture slice has the type of the argument at position i in the previous step.
The capture arg's Type is a comma-separated list of types that the Value produces. If the type list has more than one entry, e.g. "int, error" then the captured value captures a tuple result type instead of a single value. Each field in the tuple can be accessed by index by adding ".N" for any decimal N to a "$" replacement token e.g. "$name.0" or "$0.3".
All inputs and outputs must be accounted for. This can be achieved by capturing a value, or part of a tuple value, to a capture field with a type of "_". For a tuple value, each discarded element of the tuple must be explicitly discarded, for example with a capture type specified like "int, _, _".
Formatter describes how the captured arguments or results are rewritten as the input arguments to the inner function, or as the outer function's return arguments.
For example, given some function `Foo(x float64) float64`, you can imagine some outer wrapping function using an ArgRewriters that converts it into `func(x float64) (float64, float64) => math.Modf(Foo(x))`, with the following ArgRewriter values:
Input: ArgRewriter{ Capture: []Field{{Name: "x", Type: "float64", Value: "$x"},}, Formatter: "$0", } Output: ArgRewriter{ Capture: []Field{ {Type: "float64, float64", Value: "math.Modf($x)"}, }, Formatter: "$0.0, $0.1", }
type Argument ¶
Argument represents a named and typed argument e.g. a type constraint or an argument to a function.
type BuiltinFieldExpression ¶
type BuiltinFieldExpression string
BuiltinFieldExpression is a FieldExpression-like value with a constant builtin FieldExpressionType.
type Field ¶
type Field struct { Name string Type string Tag string Comment string // For fields appearing in structs that have been mapped only... Reverse FieldMapper Converter BuiltinFieldExpression // x=y; See [StructConverter]. Comparer BuiltinFieldExpression // x==y; See [Struct.Comparer]. Copier BuiltinFieldExpression // x=x; See [Struct.Copier]. Orderer BuiltinFieldExpression // x<y; See [Struct.Orderer]. Zeroer BuiltinFieldExpression // x=0; See [Struct.Zeroer]. Truther BuiltinFieldExpression // x!=0; See [Struct.Truther]. // Custom are field expressions indexed by the FieldExpressionType's Name. // If set, they define a custom operation on the field. Custom []FieldExpression }
Field represents a named and typed field in a struct, with optional struct tags, comments, and various "expressions" describing operations on fields of that type.
Fields should be considered readonly, except inside a FieldMapper.
The Tag, if any, does not include surrounding quote marks, and the Comment, if any, does not have a trailing new line or comment characters such as "//", a starting "/*", or an ending "*/".
A field appearing in a struct may also define a reverse function, which is a FieldMapper that performs the opposite conversion of a FieldMapper applied to the field. It is not necessary that the result of applying a reverse function is itself reversible. Not all mappings are reversible, so this may be set to nil.
For example, if a FieldMapper applies a transformation with
Converter == "$dest.$ = $src.$ * 2"
Then the reverse function should apply a transformation with
Converter == "$dest.$ = $src.$ / 2"
When creating a reverse function, care should be taken to not overwrite a field's existing reverse function. This can be achieved by composing the two functions with the Compose function in the fieldmappers sub package, for example:
myNewField.Reverse = fieldmappers.Compose(newfunc, myOldField.Reverse))
(this is safe even when myOldField.Reverse is nil).
func (*Field) AppendComments ¶
AppendComments appends a comment to the field's existing comment string (if any), joined with a newline separator.
Note that this modifies the field in-place, so should be done on a copy where appropriate.
func (*Field) AppendTags ¶
AppendTags appends a tag to the field's existing tags (if any), joined with a space separator, as is the convention.
Note that this modifies the field in-place, so should be done on a copy where appropriate.
Each tag in the tags list to be appended should be a single key:value pair.
If a tag in the tags list to be appended is already present in the original struct tag string, it is not appended.
If any tags do not have the conventional format, the value returned is unspecified.
func (Field) GetCustomExpression ¶
func (f Field) GetCustomExpression(name string) *FieldExpression
GetCustomExpression retrieves a named custom field expression from a field's slice of custom expressions, or nil if not found.
func (*Field) Rewrite ¶
Rewrite performs the special '$' replacement of a field's Name and Type described by FieldMapper.
Note that this modifies the field in-place, so should be done on a copy where appropriate.
func (*Field) SetCustomExpression ¶
func (f *Field) SetCustomExpression(expression FieldExpression)
SetCustomExpression adds a custom field expression to a field's slice of custom expressions or, if one with that name already exists, replaces that expression.
type FieldExpression ¶
type FieldExpression struct { Type *FieldExpressionType Pattern string // e.g. "$dest.$ = append([]$src.$.$type(nil), $src.$)" }
FieldExpression is an instruction describing how to assign, compare, or inspect, or perform some other operation on a field or fields.
Most users will just call [Struct.Converter], Struct.Comparer, etc. and do not need to use this unless using Morph to make their own custom function generators.
A field expression's Type defines what the expression does e.g. compare, convert, etc.
An expression may apply to either a single field on one struct value, or on two matching fields on two struct values, depending on the Type.
Note one important limitation: expressions of the same Type overwrite each other and do not nest. Two field mappings are incompatible if they touch the same expressions on the same fields. When making multiple incompatible mappings, you must create intermediate temporary struct types.
A field expression's Pattern defines how a field expression of that Type is applied to a specific field or fields.
These are either boolean comparison expressions (like [Field.Comparer] and [Field.Orderer]) that return true or false, value assignment expressions (like [Field.Converter] and [Field.Copier]) which assign values to a destination value, or void inspection expressions that don't return anything (but may panic). Fields are inspected in the order they appear in a source struct.
In any expression, if the pattern is the special value "skip", then it means explicitly ignore that field for expressions of that type instead of applying the default pattern for that expression type.
A field expression's pattern may contain "$-token" replacements that are replaced with a computed string when generating the source code for a new function:
"$a" and "$b" are replaced inside two-target boolean expressions with the name of two input struct value arguments.
"$src" and "$dest" are replaced inside two-target value assignment expressions with the name of the input and output struct value arguments.
"$self" is replaced inside a single-target expression with the name of the single target struct value argument.
"$this" is replaced inside a single-target boolean or void expression with the qualified field name on the single input for the field currently being mapped.
The tokens "$a", "$b", "$src", "$dest", and "$self" may be followed by a dot and another token specifying a named field (e.g. "$src.Foo"), which is then replaced with a qualified field name on the appropriate target (e.g. "myStruct.Foo").
Alternatively, instead of a named field, the tokens "$a", "$b", "$src", "$dest", and "$self" may instead be followed by a dot and "$" when not followed by any Go identifier (e.g. "$src.$.foo" is okay, but "$src.$foo" is not), which is then replaced with the qualified field name on the appropriate target for the source field currently being mapped.
Additionally:
Any token that would otherwise be replaced by any previous pattern may also be followed by a dot and "$type", in which case they are instead replaced with the type of the referenced struct value or field value.
Any token that would otherwise be replaced by any previous pattern, including with the ".$type" suffix, may also be followed by a dot and "$title" or "$untitle", in which case the replacement has the first character forced into an uppercase or lowercase variant, respectively.
In cases where a $-token is ambiguous, use parentheses e.g. "$(foo)Bar". For example, to call a method on "$src", use "$(src).Method()", and to call a function that is a field, use "$(src.Method)()".
type FieldExpressionType ¶
type FieldExpressionType struct { // Targets specifies that this is an operation over this many input and/or // output struct values. // // Don't count any incidental input or output arguments e.g. database // handles or an error return value. These can be specified in a // function signature later. // // Allowed values are 1 and 2. Targets int // Name uniquely identifies the operation e.g. "Append". A [Field] can // only ever have one custom FieldExpression per given Name, and every // FieldExpression in a struct's list of fields that share this name must // have type fields that all point to the same FieldExpressionType. Name string // Default is a pattern applied if a pattern on a FieldExpression is the // empty string (indicating default behaviour). // // All "$"-tokens are replaced according to the rules specified by the // [FieldExpression] doc comment. // // An empty Default is treated as "skip". Default string // Returns specifies if the function is a boolean comparison expression, // value assignment expression, or a void inspection expression // (see [FieldExpression]). // // Allowed values are FieldExpressionTypeVoid, FieldExpressionTypeBool, // and FieldExpressionTypeValue. // // If the type is FieldExpressionTypeVoid, then Targets must be less than // 2. Type string // Comment is an optional comment set on a generated function e.g. // "$ converts [$src.$type] to [$dest.$type]". Leading "//" tokens are not // required, and the comment may contain linebreaks. // // The "$"-tokens "$a", "$b", "$src", "$dest", and "$self" appearing in // Comment are replaced according to the rules specified by the // [FieldExpression] doc comment. // // Additionally, the token "$", when not preceded by a dot, is (at a later // time) replaced by the name of the generated function when formatting a // function. Comment string // FieldComment is an optional comment generated above each expression for // each field e.g. "does $a.$ equal $b.$?". Leading "//" tokens are not // required, and the comment may contain linebreaks. // // All "$"-tokens are replaced according to the rules specified by the // [FieldExpression] doc comment. FieldComment string // Collect is a logical operator applied to all boolean results when // Returns is set to "bool". This must be set to a string representing // the Go boolean logical operator "&&" or "||". If set to "||", the // generated function returns true immediately on the first true value. If // set to "&&", the generated function returns false immediately on the // first false value. Collect string // Accessor returns the pattern of a FieldExpression of this type on a // given field, if one exists. If nil, calls [Field.GetCustomExpression] // with the FieldExpressionType.Name as an argument. It's likely that you // want to leave this as nil. Accessor func(f Field) string // Setter sets the field expression on a field of this FieldExpressionType. // If nil, calls [Field.SetCustomExpression] with the // FieldExpressionType.Name as an argument. It's likely that you want to // leave this as nil. Setter func(f *Field, pattern string) }
FieldExpressionType describes some operation (e.g. copier, comparer, appender) on a struct value or on two struct values that can be implemented for a specific field by a FieldExpression. This controls how to generate the Go source code for a function that performs that operation.
Most users will just call [Struct.Converter], Struct.Comparer, etc. and do not need to use this unless using Morph to generate their own custom types of functions.
type FieldMapper ¶
FieldMapper maps fields on a struct to fields on another struct.
A FieldMapper is called once for each field defined on an input struct. Each invocation of the emit callback function generates a field on the output struct.
As a shortcut, a "$" appearing in an emitted Field's Name or Type is replaced with the name or type of the input Field, respectively.
It is permitted to call the emit function zero, one, or more than one time to produce zero, one, or more fields from a single input field.
For example, for an input:
Field{Name: "Foo", Type: "int64"},
Then calling emit with the argument:
emit(Field{Name: "$Slice", Type: "[]$"})
Would generate a Field with the name "FooSlice" and type `[]int64`.
Example ¶
package main import ( "fmt" "github.com/tawesoft/morph" "github.com/tawesoft/morph/fieldmappers" "github.com/tawesoft/morph/structmappers" ) func must[X any](value X, err error) X { if err != nil { panic(err) } return value } func main() { source := ` package example type Apple struct { Picked time.Time LastEaten time.Time Weight weight.Weight } ` apple := must(morph.ParseStruct("test.go", source, "")) WeightToInt64 := func(input morph.Field, emit func(output morph.Field)) { if input.Type == "weight.Weight" { output := input // copy output.Type = "int64" // rewrite the type emit(output) } else { emit(input) } } orange := apple.Map( structmappers.Rename("Orange"), ).MapFields( fieldmappers.TimeToInt64, WeightToInt64, ) fmt.Println(orange) }
Output: type Orange struct { Picked int64 // time in seconds since Unix epoch LastEaten int64 // time in seconds since Unix epoch Weight int64 }
func (FieldMapper) StructMapper ¶
func (mapper FieldMapper) StructMapper() StructMapper
StructMapper returns a new StructMapper that applies the given FieldMapper to every field on the input struct.
If the FieldMapper is reversible, then so is the returned StructMapper.
type Function ¶
type Function struct { Signature FunctionSignature Body string }
Function contains a parsed function signature and the raw source code of its body, excluding the enclosing "{" and "}" braces.
func StructConverter ¶
StructConverter uses each field's defined Converter BuiltinFieldExpression to generate a function that maps values from one struct type to another struct type.
Converter is an assignment FieldExpression-like value for mapping a field on a source struct value to a field on a destination struct.
The default is to assign the source field unchanged using "=".
The signature argument is the function signature for the generated function (omit any leading "func" keyword). This supports the $-token replacements described in FieldExpression.
func (Function) String ¶
String formats a function or method as Go source code.
For example, gives a result like:
// Foo bars a baz. func Foo(baz Baz) Bar { /* function body */ }
func (Function) Wrap ¶
func (f Function) Wrap() WrappedFunction
Wrap turns a function into a wrapped function, ready for further wrapping.
type FunctionError ¶
type FunctionError struct { Message string Signature FunctionSignature Reason error }
func (FunctionError) Error ¶
func (e FunctionError) Error() string
type FunctionSignature ¶
type FunctionSignature struct { Comment string Name string Type []Argument Arguments []Argument Returns []Argument Receiver Argument }
FunctionSignature represents a parsed function signature, including any arguments, return types, method receiver, generic type constraints, etc.
func ParseFirstFunctionSignature ¶
func ParseFirstFunctionSignature(filename string, src any) (result FunctionSignature, err error)
ParseFirstFunctionSignature is like ParseFunctionSignature, except it will return the first function found (including methods).
If src != nil, ParseFirstFunctionSignature parses the source from src and the filename is only used when recording position information. The type of the argument for the src parameter must be string, []byte, or io.Reader. If src == nil, instead parses the file specified by filename. This matches the behavior of go.Parser/ParseFile.
Parsing is performed without full object resolution. This means parsing will still succeed even on some files that may not actually compile.
func ParseFunctionSignature ¶
func ParseFunctionSignature(filename string, src any, name string) (result FunctionSignature, err error)
ParseFunctionSignature parses a given source file, looking for a function with the given name, and recording its signature.
ParseFunctionSignature does not look for any methods on a type. For this, use ParseMethodSignature instead.
If src != nil, ParseFunctionSignature parses the source from src and the filename is only used when recording position information. The type of the argument for the src parameter must be string, []byte, or io.Reader. If src == nil, instead parses the file specified by filename. This matches the behavior of go.Parser/ParseFile.
Parsing is performed without full object resolution. This means parsing will still succeed even on some files that may not actually compile.
func ParseMethodSignature ¶
func ParseMethodSignature(filename string, src any, Type string, name string) (result FunctionSignature, err error)
ParseMethodSignature is like ParseFunctionSignature, except it will match functions that are methods on the given type.
If src != nil, ParseFunction parses the source from src and the filename is only used when recording position information. The type of the argument for the src parameter must be string, []byte, or io.Reader. If src == nil, instead parses the file specified by filename. This matches the behavior of go.Parser/ParseFile.
For example, to look for a method signature such as `func (foo *Bar) Baz()`, i.e. method Baz on type Bar with a pointer receiver, then set the name argument to "Baz" and the type argument to "Bar" (it does not matter that foo is a pointer type). Generic type constraints are ignored.
Parsing is performed without full object resolution. This means parsing will still succeed even on some files that may not actually compile.
func (FunctionSignature) Copy ¶
func (fs FunctionSignature) Copy() FunctionSignature
Copy returns a (deep) copy of a FunctionSignature, ensuring that slices aren't aliased.
func (FunctionSignature) Inputs ¶
func (fs FunctionSignature) Inputs() []Argument
Inputs returns a slice containing a Argument for each input specified by the function signature, including the method receiver (if any) as the first argument.
func (FunctionSignature) String ¶
func (fs FunctionSignature) String() string
String formats the function signature as Go source code, omitting the leading "func" keyword.
func (FunctionSignature) Value ¶
func (fs FunctionSignature) Value() (string, error)
Value formats the function signature as Go source code as a value, without the leading func keyword, and its name omitted.
Methods are rewritten as functions with their receiver inserted at the start of the function's arguments.
Generic functions cannot be written this way.
type FunctionWrapper ¶
type FunctionWrapper func(in WrappedFunction) (WrappedFunction, error)
type Struct ¶
type Struct struct { Comment string Name string TypeParams []Field Fields []Field Reverse StructMapper }
Struct represents a Go struct - it's type name, type constraints (if using generics), doc comment, and fields.
If the struct has been renamed, From is its previous name. Otherwise, it is the empty string.
func ParseStruct ¶
ParseStruct parses a given source file, looking for a struct type definition that defines a struct type with the given name.
If name == "", ParseStruct returns the first struct found.
If src != nil, ParseStruct parses the source from src and the filename is only used when recording position information. The type of the argument for the src parameter must be string, []byte, or io.Reader. If src == nil, instead parses the file specified by filename. This matches the behavior of go/parser.ParseFile.
Parsing is performed without full object resolution. This means parsing will still succeed even on some files that may not actually compile.
ParseStruct only looks for struct type definitions in the top-level scope. This means that type definitions inside functions, etc. will be ignored.
Example (FromFile) ¶
package main import ( "fmt" "github.com/tawesoft/morph" ) func must[X any](value X, err error) X { if err != nil { panic(err) } return value } func main() { animal := must(morph.ParseStruct("examples_doc_test.go", nil, "Animal")) fmt.Println(animal) }
Output: type Animal struct { Name string Born time.Time }
Example (FromString) ¶
package main import ( "fmt" "github.com/tawesoft/morph" ) func must[X any](value X, err error) X { if err != nil { panic(err) } return value } func main() { source := ` package example type Apple struct { Picked time.Time LastEaten time.Time Weight weight.Weight Price price.Price } ` apple := must(morph.ParseStruct("test.go", source, "Apple")) fmt.Println(apple) }
Output: type Apple struct { Picked time.Time LastEaten time.Time Weight weight.Weight Price price.Price }
func (Struct) Comparer ¶
Comparer uses each field's defined Comparer BuiltinFieldExpression to generate a function that compares two struct values of the same type, returning true if all matching fields compare equal.
Comparer is a boolean FieldExpression-like value for comparing two matching fields on struct values of the same type, returning true if they compare equal.
A function generated using this expression returns immediately on evaluating any expression that evaluates to false.
The default is to compare with "==".
The signature argument is the function signature for the generated function (omit any leading "func" keyword). This supports the $-token replacements described in FieldExpression.
func (Struct) Copier ¶
Copier uses each field's defined Copier BuiltinFieldExpression to copy a source struct value to a destination struct value of the same type.
CopierFieldExpression is an assignment FieldExpression-like value for mapping a field value on a source struct value to a matching field value on a destination struct value of the same type.
The default is to assign with "=".
The signature argument is the function signature for the generated function (omit any leading "func" keyword). This supports the $-token replacements described in FieldExpression.
func (Struct) CustomBinaryFunction ¶
func (s Struct) CustomBinaryFunction(operation string, signature string, other Struct) (Function, error)
CustomBinaryFunction TODO docs
The struct specified as the method receiver is treated as argument "$a" or "$dest" for $-token replacement. The argument specified as "other" is treated as argument "$b" or "$src" for $-token replacement.
func (Struct) CustomUnaryFunction ¶
func (Struct) Map ¶
func (s Struct) Map(mappers ...StructMapper) Struct
Map applies each given StructMapper (in order of the arguments provided) to a struct and returns the result.
func (Struct) MapFields ¶
func (s Struct) MapFields(mappers ...FieldMapper) Struct
MapFields applies each given FieldMapper (in order of the arguments provided) to a struct and returns the result.
func (Struct) Orderer ¶
Orderer uses each field's defined Orderer BuiltinFieldExpression to generate a function that compares two struct values of the same type, returning true if all matching fields of the first compare less than all matching fields of the second.
Orderer is a boolean FieldExpression-like value for comparing two matching fields on struct values of the same type, returning true if the first is less than the second.
A function generated using this expression returns immediately on evaluating any expression that evaluates to false.
The default is to compare with "<".
The signature argument is the function signature for the generated function (omit any leading "func" keyword). This supports the $-token replacements described in FieldExpression.
func (Struct) Signature ¶
Signature returns the Go type signature of a struct as a string, including any generic type constraints, omitting the "type" and "struct" keywords.
For example, returns a result like "Orange" or "Orange[X, Y any]".
func (Struct) String ¶
String returns a Go source code representation of the given struct.
For example, returns a result like:
// Foo is a thing that bars. type Foo struct { Field Type `tag:"value"` // Comment }
func (Struct) Truther ¶
Truther uses each field's defined Truther BuiltinFieldExpression to generate a function that returns true if a struct is considered true.
Truther is a boolean FieldExpression-like value for comparing a single field to a concept of zero or false.
A function generated using this expression returns immediately on evaluating any field that evaluates to non-zero.
The default is to compare with the Go-defined zero value for that type.
The signature argument is the function signature for the generated function (omit any leading "func" keyword). This supports the $-token replacements described in FieldExpression.
func (Struct) Zeroer ¶
Zeroer uses each field's defined Zeroer BuiltinFieldExpression to generate a function that sets a struct value to its zero value.
Zeroer is an assignment FieldExpression-like value for setting a single field to its zero value.
The default is to skip the assignment, leaving the field at the zero type for that type as specified by the Go language.
The signature argument is the function signature for the generated function (omit any leading "func" keyword). This supports the $-token replacements described in FieldExpression.
Note: to conditionally zero a field, use Struct.Copier instead.
type StructMapper ¶
StructMapper maps a Struct to another Struct.
type WrappedFunction ¶
type WrappedFunction struct { Signature FunctionSignature Inputs ArgRewriter // Rewritten inputs to wrapped function Outputs ArgRewriter // Rewritten outputs from wrapped function Wraps *WrappedFunction }
func (WrappedFunction) Format ¶
func (w WrappedFunction) Format() (string, error)
func (WrappedFunction) Function ¶
func (w WrappedFunction) Function() (Function, error)
Function returns the result of converting a wrapped function into a concrete implementation representing Go source code.
func (WrappedFunction) String ¶
func (w WrappedFunction) String() string
String returns the result of WrappedFunction.Format.
In the event of error, a suitable error message is formatted as a Go comment literal, instead.
func (WrappedFunction) Wrap ¶
func (f WrappedFunction) Wrap(wrappers ...FunctionWrapper) (WrappedFunction, error)
Wrap applies function wrappers to a given wrapped function.
The earliest wrappers in the list are the first to be applied.
For example, analogous to function composition, `x.Wrap(f, g)` applies `g(f(x))`.
Returns the first error encountered.
Directories
¶
Path | Synopsis |
---|---|
Package fieldmappers provides helpful composable functions that implement [morph.FieldMapper] for mapping the fields between two structs using morph.
|
Package fieldmappers provides helpful composable functions that implement [morph.FieldMapper] for mapping the fields between two structs using morph. |
fieldops
Package fieldops implements morph FieldMappers that set appropriate Comparer, Copier, and Orderer expressions on morph Fields.
|
Package fieldops implements morph FieldMappers that set appropriate Comparer, Copier, and Orderer expressions on morph Fields. |
Package structmappers implements some useful transformations from one struct to another, in a "functional options" style for the [morph.Struct.Map] method.
|
Package structmappers implements some useful transformations from one struct to another, in a "functional options" style for the [morph.Struct.Map] method. |
Package tag provides useful features for manipulating struct field tags.
|
Package tag provides useful features for manipulating struct field tags. |