transformObject returns the code to transform source attribute of object type to target attribute of object type. It returns an error if source and target are not compatible for transformation.
(source, target *expr.AttributeExpr, sourceVar, targetVar string, newVar bool, ta *transformAttrs)
| 212 | // type to target attribute of object type. It returns an error if source |
| 213 | // and target are not compatible for transformation. |
| 214 | func transformObject(source, target *expr.AttributeExpr, sourceVar, targetVar string, newVar bool, ta *transformAttrs) (string, error) { |
| 215 | var ( |
| 216 | initCode string |
| 217 | postInitCode string |
| 218 | ) |
| 219 | { |
| 220 | // iterate through primitive attributes to initialize the struct |
| 221 | walkMatches(source, target, func(srcMatt, tgtMatt *expr.MappedAttributeExpr, srcc, tgtc *expr.AttributeExpr, n string) { |
| 222 | if !expr.IsPrimitive(srcc.Type) { |
| 223 | return |
| 224 | } |
| 225 | var ( |
| 226 | exp string |
| 227 | srcField = sourceVar + "." + ta.SourceCtx.Scope.Field(srcc, srcMatt.ElemName(n), true) |
| 228 | tgtField = ta.TargetCtx.Scope.Field(tgtc, tgtMatt.ElemName(n), true) |
| 229 | srcPtr = ta.SourceCtx.IsPrimitivePointer(n, srcMatt.AttributeExpr) |
| 230 | tgtPtr = ta.TargetCtx.IsPrimitivePointer(n, tgtMatt.AttributeExpr) |
| 231 | srcFieldConv = convertType(srcc, tgtc, srcPtr, tgtPtr, srcField, ta) |
| 232 | _, isSrcUT = srcc.Type.(expr.UserType) |
| 233 | _, isTgtUT = tgtc.Type.(expr.UserType) |
| 234 | ) |
| 235 | switch { |
| 236 | case isSrcUT || isTgtUT || (srcField != srcFieldConv): |
| 237 | var deref string |
| 238 | if srcPtr { |
| 239 | deref = "*" |
| 240 | } |
| 241 | exp = srcFieldConv |
| 242 | if isSrcUT && !ta.proto { |
| 243 | // If the source is an alias type and the code is initializing a service |
| 244 | // type then we must cast to the alias type. |
| 245 | exp = fmt.Sprintf("%s(%s%s)", ta.TargetCtx.Scope.Ref(tgtc, ta.TargetCtx.Pkg(tgtc)), deref, srcField) |
| 246 | } |
| 247 | if srcPtr && !srcMatt.IsRequired(n) { |
| 248 | postInitCode += fmt.Sprintf("if %s != nil {\n", srcField) |
| 249 | if tgtPtr { |
| 250 | tmp := codegen.Goify(tgtMatt.ElemName(n), false) |
| 251 | postInitCode += fmt.Sprintf("%s := %s\n%s.%s = &%s\n", tmp, exp, targetVar, tgtField, tmp) |
| 252 | } else { |
| 253 | postInitCode += fmt.Sprintf("%s.%s = %s\n", targetVar, tgtField, exp) |
| 254 | } |
| 255 | postInitCode += "}\n" |
| 256 | return |
| 257 | } else if tgtPtr { |
| 258 | tmp := codegen.Goify(tgtMatt.ElemName(n), false) |
| 259 | postInitCode += fmt.Sprintf("%s := %s\n%s.%s = &%s\n", tmp, exp, targetVar, tgtField, tmp) |
| 260 | return |
| 261 | } |
| 262 | case srcPtr && !tgtPtr: |
| 263 | exp = "*" + srcField |
| 264 | if !srcMatt.IsRequired(n) { |
| 265 | postInitCode += fmt.Sprintf("if %s != nil {\n\t%s.%s = %s\n}\n", srcField, targetVar, tgtField, exp) |
| 266 | return |
| 267 | } |
| 268 | case !srcPtr && tgtPtr: |
| 269 | exp = "&" + srcField |
| 270 | default: |
| 271 | exp = srcField |
no test coverage detected