// UserTypeUnmarshalerImpl returns the code implementing the user type unmarshaler function. func UserTypeUnmarshalerImpl(u *design.UserTypeDefinition, context string) string { var required []string for _, v := range u.Validations { if r, ok := v.(*design.RequiredValidationDefinition); ok { required = r.Names break } } var impl string switch { case u.IsObject(): impl = objectUnmarshalerR(u, required, context, "source", "target", 1) case u.IsArray(): impl = arrayUnmarshalerR(u.ToArray(), context, "source", "target", 1) case u.IsHash(): impl = hashUnmarshalerR(u.ToHash(), 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, } return RunTemplate(unmUserImplT, data) }
// Type implements the type definition DSL. A type definition describes a data structure consisting // of attributes. Each attribute has a type which can also refer to a type definition (or use a // primitive type or nested attibutes). The DSL syntax for define a type definition is the // Attribute DSL, see Attribute. // // On top of specifying any attribute type, type definitions can also be used to describe the data // structure of a request payload. They can also be used by media type definitions as reference, see // Reference. Here is an example: // // Type("createPayload", func() { // Description("Type of create and upload action payloads") // APIVersion("1.0") // Attribute("name", String, "name of bottle") // Attribute("origin", Origin, "Details on wine origin") // See Origin definition below // Required("name") // }) // // var Origin = Type("origin", func() { // Description("Origin of bottle") // Attribute("Country") // }) // // This function returns the newly defined type so the value can be used throughout the DSL. func Type(name string, dsl func()) *design.UserTypeDefinition { if design.Design.Types == nil { design.Design.Types = make(map[string]*design.UserTypeDefinition) } else if _, ok := design.Design.Types[name]; ok { ReportError("type %#v defined twice", name) return nil } var t *design.UserTypeDefinition if topLevelDefinition(true) { t = &design.UserTypeDefinition{ TypeName: name, AttributeDefinition: &design.AttributeDefinition{DSLFunc: dsl}, } if dsl == nil { t.Type = design.String } design.Design.Types[name] = t } return t }
// userTypeUnmarshalerFuncName returns the name for the given user type unmarshaler function. func userTypeUnmarshalerFuncName(u *design.UserTypeDefinition) string { return fmt.Sprintf("Unmarshal%s", GoTypeName(u, u.AllRequired(), 0)) }
// 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) }