transformAttributeHelpers returns the Go transform functions and their definitions that may be used in code produced by Transform. It returns an error if source and target are incompatible (different types, fields of different type etc). source, target are the source and target attributes used in t
(source, target *expr.AttributeExpr, ta *transformAttrs, seen map[string]*codegen.TransformFunctionData)
| 877 | // |
| 878 | // seen keeps track of generated transform functions to avoid recursion |
| 879 | func transformAttributeHelpers(source, target *expr.AttributeExpr, ta *transformAttrs, seen map[string]*codegen.TransformFunctionData) ([]*codegen.TransformFunctionData, error) { |
| 880 | var ( |
| 881 | helpers []*codegen.TransformFunctionData |
| 882 | err error |
| 883 | ) |
| 884 | { |
| 885 | if err = codegen.IsCompatible(source.Type, target.Type, "", ""); err != nil { |
| 886 | if ta.proto { |
| 887 | target = unwrapAttr(expr.DupAtt(target)) |
| 888 | } else { |
| 889 | source = unwrapAttr(expr.DupAtt(source)) |
| 890 | } |
| 891 | if err = codegen.IsCompatible(source.Type, target.Type, "", ""); err != nil { |
| 892 | return nil, err |
| 893 | } |
| 894 | } |
| 895 | // Do not generate a transform function for the top most user type. |
| 896 | switch { |
| 897 | case expr.IsArray(source.Type): |
| 898 | source = expr.AsArray(source.Type).ElemType |
| 899 | target = expr.AsArray(target.Type).ElemType |
| 900 | helpers, err = transformAttributeHelpers(source, target, ta, seen) |
| 901 | case expr.IsMap(source.Type): |
| 902 | sm := expr.AsMap(source.Type) |
| 903 | tm := expr.AsMap(target.Type) |
| 904 | helpers, err = transformAttributeHelpers(sm.ElemType, tm.ElemType, ta, seen) |
| 905 | if err == nil { |
| 906 | var other []*codegen.TransformFunctionData |
| 907 | other, err = transformAttributeHelpers(sm.KeyType, tm.KeyType, ta, seen) |
| 908 | helpers = append(helpers, other...) |
| 909 | } |
| 910 | case expr.IsUnion(source.Type): |
| 911 | srcAttrs := expr.AsUnion(source.Type) |
| 912 | tgtAttrs := expr.AsUnion(target.Type) |
| 913 | if len(srcAttrs.Values) != len(tgtAttrs.Values) { |
| 914 | return nil, fmt.Errorf("cannot transform union attribute %s with %d types to union attribute %s with %d types", |
| 915 | source.Type.Name(), len(srcAttrs.Values), target.Type.Name(), len(tgtAttrs.Values)) |
| 916 | } |
| 917 | for i, srcAtt := range srcAttrs.Values { |
| 918 | tgtAtt := tgtAttrs.Values[i] |
| 919 | h, err := collectHelpers(srcAtt.Attribute, tgtAtt.Attribute, true, ta, seen) |
| 920 | if err == nil { |
| 921 | helpers = append(helpers, h...) |
| 922 | } |
| 923 | } |
| 924 | case expr.IsObject(source.Type): |
| 925 | walkMatches(source, target, func(srcMatt, _ *expr.MappedAttributeExpr, srcc, tgtc *expr.AttributeExpr, n string) { |
| 926 | if err != nil { |
| 927 | return |
| 928 | } |
| 929 | if err = codegen.IsCompatible(srcc.Type, tgtc.Type, "", ""); err != nil { |
| 930 | if ta.proto { |
| 931 | tgtc = unwrapAttr(tgtc) |
| 932 | } else { |
| 933 | srcc = unwrapAttr(srcc) |
| 934 | } |
| 935 | if err = codegen.IsCompatible(srcc.Type, tgtc.Type, "", ""); err != nil { |
| 936 | return |
no test coverage detected