Documentation ¶
Index ¶
- func Decode(resolver TypeResolver, source map[string]any, output any) error
- func NewPolymorphismBuilder() polymorphismBuilderEmpty
- func NewRuleBuilder() ruleBuilderBase
- func UnmarshalJSON(resolver TypeResolver, data []byte, output any) error
- type Polymorphism
- type Rule
- type RulePolymorphism
- type TypeMap
- type TypeMapPolymorphism
- type TypeResolver
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Decode ¶
func Decode(resolver TypeResolver, source map[string]any, output any) error
Decode the given source map into the given output object using the given TypeResolver and mapstructure. The output object must be a pointer.
func NewPolymorphismBuilder ¶
func NewPolymorphismBuilder() polymorphismBuilderEmpty
NewPolymorphismBuilder creates a new polymorphism builder that is used in a human readable way to create a polymorphism. It only allows a valid combination of rules and type maps.
func NewRuleBuilder ¶
func NewRuleBuilder() ruleBuilderBase
NewRuleBuilder creates a new ruleBuilder. It enables a fluent interface for building a Rule.
func UnmarshalJSON ¶
func UnmarshalJSON(resolver TypeResolver, data []byte, output any) error
UnmarshalJSON unmarshals the given JSON data into the given output object using the given TypeResolver.
Example ¶
ExampleUnmarshalJSON demonstrates how to use the polymorpher to unmarshal a JSON into a struct with a polymorphic field.
package main import ( "fmt" "github.com/SoulKa/golymorph" "reflect" ) func main() { // get a JSON that contains a payload with a type field that determines the type of the payload alertEventJson := `{ "timestamp": "2023-11-27T22:14:09+00:00", "payload": { "type": "alert", "message": "something is broken!" } }` // the parent type that contains the polymorphic payload type Event struct { Timestamp string Payload any } // the polymorphic child types type AlertPayload struct { Type string Message string } type PingPayload struct { Type string Ip string } // define a mapping from the type value to the type of the payload typeMap := golymorph.TypeMap{ "alert": reflect.TypeOf(AlertPayload{}), "ping": reflect.TypeOf(PingPayload{}), } // create a TypeResolver that assigns the type of the payload based on the type field err, resolver := golymorph.NewPolymorphismBuilder(). DefineTypeAt("payload"). UsingTypeMap(typeMap). WithDiscriminatorAt("type"). Build() if err != nil { panic(fmt.Sprintf("error building polymorpher: %s", err)) } // create a new event var event Event if err := golymorph.UnmarshalJSON(resolver, []byte(alertEventJson), &event); err != nil { panic(fmt.Sprintf("error unmarshalling event: %s", err)) } // continue to work with the event fmt.Printf("event: %+v\n", event) fmt.Printf("event payload: %T %+v\n", event.Payload, event.Payload.(AlertPayload)) }
Output: event: {Timestamp:2023-11-27T22:14:09+00:00 Payload:{Type:alert Message:something is broken!}} event payload: golymorph_test.AlertPayload {Type:alert Message:something is broken!}
Types ¶
type Polymorphism ¶
type Polymorphism struct { // TargetPath is the path to the object to assign the new type to TargetPath objectpath.ObjectPath }
Polymorphism is the base struct for all polymorphism mappers. It contains the target path to assign the new type to.
type Rule ¶
type Rule struct { // ValuePath is the path to the value in the source to compare. ValuePath objectpath.ObjectPath // ComparatorFunction is the function to use to compare the value at ValuePath to. ComparatorFunction func(any) bool // NewType is the type to assign to the target if the rule matches. NewType reflect.Type }
Rule is a rule for a polymorphism mapper.
type RulePolymorphism ¶
type RulePolymorphism struct { Polymorphism // Rules is a list of Rules to apply. The first rule that matches is used to determine the target type. Rules []Rule }
RulePolymorphism is a mapper that assigns a target type based on the given Rules
func (*RulePolymorphism) AssignTargetType ¶
func (p *RulePolymorphism) AssignTargetType(source any, target any) error
type TypeMapPolymorphism ¶
type TypeMapPolymorphism struct { Polymorphism // DiscriminatorPath is the path to the discriminator value DiscriminatorPath objectpath.ObjectPath // TypeMap is a map of discriminator values to types TypeMap TypeMap }
TypeMapPolymorphism is a mapper that assigns a target type based on a discriminator value and a type map
func (*TypeMapPolymorphism) AssignTargetType ¶
func (p *TypeMapPolymorphism) AssignTargetType(source any, target any) error
Example ¶
ExampleTypeMapPolymorphism_AssignTargetType demonstrates how to use the polymorpher to assign the type of a polymorphic field in an existing struct instance.
package main import ( "encoding/json" "fmt" "github.com/SoulKa/golymorph" "github.com/mitchellh/mapstructure" "reflect" ) func main() { // get a JSON that contains a payload with a type field that determines the type of the payload alertEventJson := `{ "timestamp": "2023-11-27T22:14:09+00:00", "payload": { "type": "alert", "message": "something is broken!" } }` type Event struct { Timestamp string Payload any } type AlertPayload struct { Type string Message string } type PingPayload struct { Type string Ip string } typeMap := golymorph.TypeMap{ "alert": reflect.TypeOf(AlertPayload{}), "ping": reflect.TypeOf(PingPayload{}), } // parse the JSON into a map var jsonMap map[string]any if err := json.Unmarshal([]byte(alertEventJson), &jsonMap); err != nil { panic(fmt.Sprintf("error unmarshalling JSON: %s", err)) } // create a polymorpher that assigns the type of the payload based on the type field err, polymorpher := golymorph.NewPolymorphismBuilder(). DefineTypeAt("payload"). UsingTypeMap(typeMap). WithDiscriminatorAt("type"). Build() if err != nil { panic(fmt.Sprintf("error building polymorpher: %s", err)) } // create a new event var event Event if err := polymorpher.AssignTargetType(&jsonMap, &event); err != nil { panic(fmt.Sprintf("error assigning target type: %s", err)) } // use mapstructure to unmarshal the payload into the event if err := mapstructure.Decode(jsonMap, &event); err != nil { panic(fmt.Sprintf("error decoding JSON map: %s", err)) } // continue to work with the event fmt.Printf("event: %+v\n", event) fmt.Printf("event payload: %T %+v\n", event.Payload, event.Payload.(AlertPayload)) }
Output: event: {Timestamp:2023-11-27T22:14:09+00:00 Payload:{Type:alert Message:something is broken!}} event payload: golymorph_test.AlertPayload {Type:alert Message:something is broken!}
type TypeResolver ¶
type TypeResolver interface { // AssignTargetType assigns the determined type to target based on the polymorphism rules. The matching rule with the // highest priority is used. If no rule matches, the target type is not changed. The source and target must be pointers. // If no matching type can be determined, an error.UnresolvedTypeError is returned. AssignTargetType(source any, target any) error }
TypeResolver is an interface that can resolve the type of a target based on the values of a source.