Documentation ¶
Overview ¶
Package argmapper is a dependency-injection library for Go.
go-argmapper supports named values, typed values, automatically chaining conversion functions to reach desired types, and more. go-argmapper is designed for runtime, reflection-based dependency injection.
The primary usage of this library is via the Func struct. See Func for more documentation.
Index ¶
- func Convert(target reflect.Type, opts ...Arg) (interface{}, error)
- type Arg
- func Converter(fs ...interface{}) Arg
- func ConverterFunc(fs ...*Func) Arg
- func ConverterGen(fs ...ConverterGenFunc) Arg
- func FilterInput(f FilterFunc) Arg
- func FilterOutput(f FilterFunc) Arg
- func FuncName(n string) Arg
- func FuncOnce() Arg
- func Logger(l hclog.Logger) Arg
- func Named(n string, v interface{}) Arg
- func NamedSubtype(n string, v interface{}, st string) Arg
- func Typed(vs ...interface{}) Arg
- func TypedSubtype(v interface{}, st string) Arg
- type ConverterGenFunc
- type ErrArgumentUnsatisfied
- type FilterFunc
- type Func
- type Result
- type Struct
- type Value
- type ValueKind
- type ValueSet
- func (vs *ValueSet) Args() []Arg
- func (vs *ValueSet) FromResult(r Result) error
- func (vs *ValueSet) FromSignature(values []reflect.Value) error
- func (vs *ValueSet) Named(n string) *Value
- func (vs *ValueSet) Signature() []reflect.Type
- func (vs *ValueSet) SignatureValues() []reflect.Value
- func (vs *ValueSet) Typed(t reflect.Type) *Value
- func (vs *ValueSet) TypedSubtype(t reflect.Type, st string) *Value
- func (vs *ValueSet) Values() []Value
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Arg ¶
type Arg func(*argBuilder) error
Arg is an option to Func.Call that sets the state for the function call. This can be a direct named arg or a converter that could be used if necessary to reach the target.
func Converter ¶
func Converter(fs ...interface{}) Arg
Converter specifies one or more converters to use if necessary. A converter will be used if an argument type doesn't match exactly.
func ConverterFunc ¶
ConverterFunc is the same as Converter but takes an already created Func value. Any nil arguments are ignored. This appends to the list of converters.
func ConverterGen ¶
func ConverterGen(fs ...ConverterGenFunc) Arg
ConverterGen registers a converter generator. A converter generator generates a converter dynamically based on some set values. This can be used to generate type conversions for example. The returned func can have more requirements.
If the function returns a nil Func, then no converter is generated.
func FilterInput ¶
func FilterInput(f FilterFunc) Arg
FilterInput is used by Func.Redefine to define what inputs are valid. This will replace any previously set FilterInput value. This has no effect unless Func.Redefine is being called.
func FilterOutput ¶
func FilterOutput(f FilterFunc) Arg
FilterOutput is identical to FilterInput but for output values. If this is not set, then Redefine will allow any output values. This behavior is the same as if FilterInput were not specified.
func FuncOnce ¶ added in v0.2.0
func FuncOnce() Arg
FuncOnce configures the function to be called at most once. The result of a function call will be memoized and any future calls to the function will return the memoized function.
This is particularly useful if there is a complex converter that may be required multiple times in a function call chain.
The downside to this is that the result is memoized regardless of the input arguments. Therefore, if the input arguments change, this function will still not be called again. Users of this should be ABSOLUTELY SURE that they want this function to run exactly once regardless of arguments and return the same result every time.
func Logger ¶
func Logger(l hclog.Logger) Arg
Logger specifies a logger to be used during operations with these arguments. If this isn't specified, the default hclog.L() logger is used.
func Named ¶
Named specifies a named argument with the given value. This will satisfy any requirement where the name matches AND the value is assignable to the struct.
If the name is an empty string, this is equivalent to calling Typed.
func NamedSubtype ¶
NamedSubtype is the same as Named but specifies a subtype for the value.
If the name is an empty string, this is the equivalent to calling TypedSubtype.
func Typed ¶
func Typed(vs ...interface{}) Arg
Typed specifies a typed argument with the given value. This will satisfy any requirement where the type is assignable to a required value. The name can be anything of the required value.
func TypedSubtype ¶
TypedSubtype is the same as Typed but specifies a subtype key for the value. If the subtype is empty, this is equivalent to calling Typed.
type ConverterGenFunc ¶
ConverterGenFunc is called with a value and should return a non-nil Func if it is able to generate a converter on the fly based on this value.
type ErrArgumentUnsatisfied ¶ added in v0.2.1
type ErrArgumentUnsatisfied struct { // Func is the target function call that was attempted. Func *Func // Args are the args that aren't satisfied. Note that this won't have // the "Value" field set because an unsatisfied argument by definition // is missing a value. Args []*Value // Inputs is the list of values that were provided directly to the // function call that we could use to populate arguments. Inputs []*Value // Converters is the list of converter functions available for use. Converters []*Func }
ErrArgumentUnsatisfied is the value returned when there is an argument to a target function that cannot be satisfied given the inputs and mappers.
func (*ErrArgumentUnsatisfied) Error ¶ added in v0.2.1
func (e *ErrArgumentUnsatisfied) Error() string
type FilterFunc ¶
func FilterAnd ¶
func FilterAnd(fs ...FilterFunc) FilterFunc
FilterAnd returns a FilterFunc that returns true if any of the given filter functions return true.
func FilterOr ¶
func FilterOr(fs ...FilterFunc) FilterFunc
FilterOr returns a FilterFunc that returns true if any of the given filter functions return true.
func FilterType ¶
func FilterType(t reflect.Type) FilterFunc
FilterType filters values based on matching the given type. If the type is an interface value then any types that implement the interface will also pass.
type Func ¶
type Func struct {
// contains filtered or unexported fields
}
Func represents both a target function you want to execute as well as a function that can be used to provide values, convert types, etc. for calling another Func.
A Func can take any number of arguments and return any number of values. Direct function arguments are matched via type. You may use a struct that embeds the Struct type (see Struct) for named value matching. Go reflection doesn't enable accessing direct function parameter names, so a struct is required for named matching.
Structs that do not embed the Struct type are matched as typed.
Converter Basics ¶
A Func also can act as a converter for another function call when used with the Converter Arg option.
Converters are used if a direct match argument isn't found for a Func call. If a converter exists (or a chain of converts) to go from the input arguments to the desired argument, then the chain will be called and the result used.
Like any typical Func, converters can take as input zero or more values of any kind. Converters can return any number of values as a result. Note that while no return values are acceptable, such a converter would never be called since it provides no value to the target function call.
Converters can output both typed and named values. Similar to inputs, outputting a name value requires using a struct with the Struct type embedded.
Converter Errors ¶
A final return type of "error" can be used with converters to signal that conversion failed. If this occurs, the full function call attempt fails and the error is reported to the user.
If there is only one return value and it is of type "error", then this is still considered the error result. A function can't return a non-erroneous error value without returning more than one result value.
Converter Priorities ¶
When multiple converters are available to reach some desired type, Func will determine which converter to call using an implicit "cost" associated with the converter. The cost is calculated across multiple dimensions:
When converting from one named value to another, such as "Input int" to "Input string", conversion will favor any converters that explicitly use the equivalent name (but different type). So if there are two converters, one `func(int) string` and another `func(Input int) string`, then the latter will be preferred.
Building on the above, if there is only one converter `func(int) string` but there are multiple `int` inputs available, an input with a matching name is preferred. Therefore, if an input named `Input` is available, that will be used for the conversion.
Converters that have less input values are preferred. This isn't a direct parameter count on the function, but a count on the input values which includes struct members and so on.
func BuildFunc ¶
func BuildFunc(input, output *ValueSet, cb func(in, out *ValueSet) error, opts ...Arg) (*Func, error)
BuildFunc builds a function based on the specified input and output value sets. When called, this will call the cb with a valueset matching input and output with the argument values set. The cb should return a populated ValueSet.
func MustFunc ¶ added in v0.2.0
MustFunc can be called around NewFunc in order to force success and panic if there is any error.
func NewFunc ¶
NewFunc creates a new Func from the given input function f.
For more details on the format of the function f, see the package docs.
Additional opts can be provided. These will always be set when calling Call. Any conflicting arguments given on Call will override these args. This can be used to provide some initial values, converters, etc.
func NewFuncList ¶
NewFuncList initializes multiple Funcs at once. This is the same as calling NewFunc for each f.
func (*Func) Call ¶
Call calls the function. Use the various Arg functions to set the state for the function call. More details on how Call works are on the Func struct documentation directly.
func (*Func) Func ¶
func (f *Func) Func() interface{}
Func returns the function pointer that this Func is built around.
func (*Func) Input ¶
Input returns the input ValueSet for this function, representing the values that this function requires as input.
func (*Func) Name ¶
Name returns the name of the function.
This will return the configured name if one was given on NewFunc. If not, this will attempt to look up the function name using the pointer. If no friendly name can be found, then this will default to the function type signature.
func (*Func) Output ¶
Output returns the output ValueSet for this function, representing the values that this function produces as an output.
func (*Func) Redefine ¶
Redefine returns a new func where the requirements are what is missing to satisfy the original function given the arguments here. Therefore, args may be incomplete, and this will return a function that only depends on the missing arguments.
Redefine also allows the usage of FilterInput and FilterOutput Arg values. These can be used to further restrict what values can be provided as an input or returned as an output, respectively. This can be used for example to try to redefine a function to only take Go primitives. In the case where Filter is used, converters must be specified that enable going to and from filtered values.
Currently, FilterOutput will just return an error if the functions outputs don't match what is expected. In the future, we plan on enabling FilterOutput to also map through converters to return the desired matches.
If it is impossible to redefine the function according to the given constraints, an error will be returned.
type Result ¶
type Result struct {
// contains filtered or unexported fields
}
Result is returned from a Call with the results of the function call.
This structure lets you access multiple results values. If the function call had a final return value type "error", this is treated specially and is present via the Err call and not via Out.
func (*Result) Err ¶
Err returns any error that occurred as part of the call. This can be an error in the process of calling or it can be an error from the result of the call.
type Struct ¶
type Struct struct {
// contains filtered or unexported fields
}
Struct should be embedded into any struct where the parameters are populated. This lets argmapper differentiate between arguments where you want the full struct provided or fields within the struct.
Example:
type MyParams { argmapper.Struct // A and B will be populated through injection. A, B int }
If the embedded Struct was left out, argmapper would look for a full MyParams type to inject.
Named Parameters ¶
By default, the field name is the name of the parameter. In the example above, MyParams expects parameters named "A" and "B", both of type int.
Parameter names are case insensitive.
Parameters can be renamed using a struct tag. The example below renames the field "A" to "B".
type MyParams { argmapper.Struct A int `argmapper:"B"` }
Typed Parameters ¶
A field in the struct can be marked as typed only using struct tags. The field name of a typed field is ignored and argmapper will match it to any matching type.
type MyParams { argmapper.Struct A int `argmapper:",typeOnly"` }
Note the comma before the "typeOnly" string. The comma is necessary so tell argmapper you're setting an option versus renaming a field.
type Value ¶
type Value struct { // Name is the name of the value. This may be empty if this is a type-only // value. If the name is set, then we will satisfy this input with an arg // with this name and type. Name string // Type is the type of the value. This must be set. Type reflect.Type // Subtype is a key that specifies a unique "subtype" for the type. // This can be used to identify dynamic values such as protobuf Any types // where the full type isn't available. This is optional. For full details // on subtype matching see the package docs. Subtype string // Value is the known value. This is only ever set if using Func.Redefine // with an input that was given. Otherwise, this value is invalid. Value reflect.Value // contains filtered or unexported fields }
Value represents an input or output of a Func. In normal operation, you do not need to interact with Value objects directly. This structure is exposed for users who are trying to introspect on functions or manually build functions. This is an advanced operation.
A Value represents multiple types of values depending on what fields are set. Please read the documentation carefully and use the exported methods to assist with checking value types.
func (*Value) Arg ¶
Arg returns an Arg that can be used with Func.Call to send this value. This only works if the Value's Value field is set.
type ValueKind ¶
type ValueKind uint
ValueKind is returned by Value.Kind to designate what kind of value this is: a value expecting a type and name, a value with just type matching, etc.
type ValueSet ¶
type ValueSet struct {
// contains filtered or unexported fields
}
ValueSet tracks the values either accepted or returned as part of a function or converter.
Internally, argmapper converts all functions to a signature of `func(Struct) (Struct, error)`. This lets the internals simplify a lot by expecting to only set struct fields. On the edges (when calling functions or returning values) we convert to and from the true expected arguments.
func NewValueSet ¶
NewValueSet creates a ValueSet from a list of expected values.
This is primarily used alongside BuildFunc to dynamically build a Func.
func (*ValueSet) Args ¶ added in v0.2.0
Args returns all of the values in this ValueSet as a slice of Arg to make it easier to pass to Call. This is equivalent to iterating over the Values result and accumulating Arg results.
func (*ValueSet) FromResult ¶
FromResult sets the values in this set based on a Result. This will return an error if the result represents an error.
func (*ValueSet) FromSignature ¶
FromSignature sets the values in this ValueSet based on the values list. The values list must match the type signature returned from vs.Signature. This usually comes from calling a function directly.
func (*ValueSet) Named ¶
Named returns a pointer to the value with the given name, or nil if it doesn't exist.
func (*ValueSet) Signature ¶
Signature returns the type signature that this ValueSet will map to/from. This is used for making dynamic types with reflect.FuncOf to take or return this valueset.
func (*ValueSet) SignatureValues ¶
SignatureValues returns the values that match the Signature type list, based on the values set in this set. If a value isn't set, the zero value is used.
func (*ValueSet) Typed ¶
Typed returns a pointer to the value with the given type, or nil if it doesn't exist. If there is no typed value directly, a random type with the matching subtype will be chosen. If you want an exact match with no subtype, use TypedSubtype.
func (*ValueSet) TypedSubtype ¶
TypedSubtype returns a pointer to the value that matches the type and subtype exactly.