// GoTypeRef returns the Go code that refers to the Go type which matches the given data type // (the part that comes after `var foo`) // required only applies when referring to a user type that is an object defined inline. In this // case the type (Object) does not carry the required field information defined in the parent // (anonymous) attribute. // tabs is used to properly tabulate the object struct fields and only applies to this case. // This function assumes the type is in the same package as the code accessing it. func GoTypeRef(t design.DataType, required []string, tabs int, private bool) string { tname := GoTypeName(t, required, tabs, private) if t.IsObject() { return "*" + tname } return tname }
// cmdFieldType computes the Go type name used to store command flags of the given design type. func cmdFieldType(t design.DataType, point bool) string { var pointer, suffix string if point && !t.IsArray() { pointer = "*" } suffix = codegen.GoNativeType(t) return pointer + suffix }
// GoTypeRef returns the Go code that refers to the Go type which matches the given data type // (the part that comes after `var foo`) // required only applies when referring to a user type that is an object defined inline. In this // case the type (Object) does not carry the required field information defined in the parent // (anonymous) attribute. // tabs is used to properly tabulate the object struct fields and only applies to this case. // This function assumes the type is in the same package as the code accessing it. func GoTypeRef(t design.DataType, required []string, tabs int, private bool) string { tname := GoTypeName(t, required, tabs, private) if mt, ok := t.(*design.MediaTypeDefinition); ok { if mt.IsError() { return "error" } } if t.IsObject() { return "*" + tname } return tname }
func isArrayOfType(array design.DataType, kinds ...design.Kind) bool { if !array.IsArray() { return false } kind := array.ToArray().ElemType.Type.Kind() for _, t := range kinds { if t == kind { return true } } return false }
// GoPackageTypeRef returns the Go code that refers to the Go type which matches the given data type. // versioned indicates whether the type is being referenced from a version package (true) or the // default package defPkg (false). // required only applies when referring to a user type that is an object defined inline. In this // case the type (Object) does not carry the required field information defined in the parent // (anonymous) attribute. // tabs is used to properly tabulate the object struct fields and only applies to this case. func GoPackageTypeRef(t design.DataType, required []string, versioned bool, defPkg string, tabs int) string { switch t.(type) { case *design.UserTypeDefinition, *design.MediaTypeDefinition: var prefix string if t.IsObject() { prefix = "*" } return prefix + GoPackageTypeName(t, required, versioned, defPkg, tabs) case design.Object: return "*" + GoPackageTypeName(t, required, versioned, defPkg, tabs) default: return GoPackageTypeName(t, required, versioned, defPkg, tabs) } }
// printVal prints the given value corresponding to the given data type. // The value is already checked for the compatibility with the data type. func printVal(t design.DataType, val interface{}) string { switch { case t.IsPrimitive(): // For primitive types, simply print the value s := fmt.Sprintf("%#v", val) if t == design.DateTime { s = fmt.Sprintf("time.Parse(time.RFC3339, %s)", s) } return s case t.IsHash(): // The input is a hash h := t.ToHash() hval := val.(map[interface{}]interface{}) if len(hval) == 0 { return fmt.Sprintf("%s{}", GoTypeName(t, nil, 0, false)) } var buffer bytes.Buffer buffer.WriteString(fmt.Sprintf("%s{", GoTypeName(t, nil, 0, false))) for k, v := range hval { buffer.WriteString(fmt.Sprintf("%s: %s, ", printVal(h.KeyType.Type, k), printVal(h.ElemType.Type, v))) } buffer.Truncate(buffer.Len() - 2) // remove ", " buffer.WriteString("}") return buffer.String() case t.IsArray(): // Input is an array a := t.ToArray() aval := val.([]interface{}) if len(aval) == 0 { return fmt.Sprintf("%s{}", GoTypeName(t, nil, 0, false)) } var buffer bytes.Buffer buffer.WriteString(fmt.Sprintf("%s{", GoTypeName(t, nil, 0, false))) for _, e := range aval { buffer.WriteString(fmt.Sprintf("%s, ", printVal(a.ElemType.Type, e))) } buffer.Truncate(buffer.Len() - 2) // remove ", " buffer.WriteString("}") return buffer.String() default: // shouldn't happen as the value's compatibility is already checked. panic("unknown type") } }
// cmdFieldTypeString computes the Go type name used to store command flags of the given design type. Complex types are String func cmdFieldTypeString(t design.DataType, point bool) string { var pointer, suffix string if point && !t.IsArray() { pointer = "*" } if t.Kind() == design.UUIDKind || t.Kind() == design.DateTimeKind || t.Kind() == design.AnyKind || t.Kind() == design.NumberKind || t.Kind() == design.BooleanKind { suffix = "string" } else if isArrayOfType(t, design.UUIDKind, design.DateTimeKind, design.AnyKind, design.NumberKind, design.BooleanKind) { suffix = "[]string" } else { suffix = codegen.GoNativeType(t) } return pointer + suffix }
// cmdFieldType computes the Go type name used to store command flags of the given design type. func cmdFieldType(t design.DataType) string { if t.Kind() == design.DateTimeKind || t.Kind() == design.UUIDKind { return "string" } return codegen.GoNativeType(t) }
// qualifiedTypeName returns the qualified type name for the given data type. // This is useful in reporting types in error messages. // (e.g) array<string>, hash<string, string>, hash<string, array<int>> func qualifiedTypeName(t design.DataType) string { switch t.Kind() { case design.DateTimeKind: return "datetime" case design.ArrayKind: return fmt.Sprintf("%s<%s>", t.Name(), qualifiedTypeName(t.ToArray().ElemType.Type)) case design.HashKind: h := t.ToHash() return fmt.Sprintf("%s<%s, %s>", t.Name(), qualifiedTypeName(h.KeyType.Type), qualifiedTypeName(h.ElemType.Type), ) } return t.Name() }