// UserTypeUnmarshalerImpl returns the code implementing the user type unmarshaler function. func UserTypeUnmarshalerImpl(u *design.UserTypeDefinition, versioned bool, defaultPkg, context string) string { validation := RecursiveChecker(u.AttributeDefinition, false, false, "source", context, 1) var impl string switch { case u.IsObject(): impl = objectUnmarshalerR(u, u.AllRequired(), u.AllNonZero(), versioned, defaultPkg, context, "source", "target", 1) case u.IsArray(): impl = arrayUnmarshalerR(u.ToArray(), versioned, defaultPkg, context, "source", "target", 1) case u.IsHash(): impl = hashUnmarshalerR(u.ToHash(), versioned, defaultPkg, context, "source", "target", 1) default: return "" // No function for primitive types - they just get casted } data := map[string]interface{}{ "Name": userTypeUnmarshalerFuncName(u), "Type": u, "Impl": impl, "MustValidate": strings.TrimSpace(validation) != "", } return RunTemplate(unmUserImplT, data) }
// GoTypeTransform produces Go code that initializes the data structure defined by target from an // instance of the data structure described by source. The algorithm matches object fields by name // or using the value of the "transform:key" attribute metadata when present. // The function returns an error if target is not compatible with source (different type, fields of // different type etc). It ignores fields in target that don't have a match in source. func GoTypeTransform(source, target *design.UserTypeDefinition, targetPkg, funcName string) (string, error) { var impl string var err error switch { case source.IsObject(): if !target.IsObject() { return "", fmt.Errorf("source is an object but target type is %s", target.Type.Name()) } impl, err = transformObject(source.ToObject(), target.ToObject(), targetPkg, target.TypeName, "source", "target", 1) case source.IsArray(): if !target.IsArray() { return "", fmt.Errorf("source is an array but target type is %s", target.Type.Name()) } impl, err = transformArray(source.ToArray(), target.ToArray(), targetPkg, "source", "target", 1) case source.IsHash(): if !target.IsHash() { return "", fmt.Errorf("source is a hash but target type is %s", target.Type.Name()) } impl, err = transformHash(source.ToHash(), target.ToHash(), targetPkg, "source", "target", 1) default: panic("cannot transform primitive types") // bug } if err != nil { return "", err } t := GoTypeRef(target, nil, 0) if strings.HasPrefix(t, "*") && len(targetPkg) > 0 { t = fmt.Sprintf("*%s.%s", targetPkg, t[1:]) } data := map[string]interface{}{ "Name": funcName, "Source": source, "Target": target, "TargetRef": t, "TargetPkg": targetPkg, "Impl": impl, } return RunTemplate(transformT, data), nil }