예제 #1
0
파일: generator.go 프로젝트: ajoulie/goa
// generateUserTypes iterates through the user types and generates the data structures and
// marshaling code.
func (g *Generator) generateUserTypes(api *design.APIDefinition) error {
	utFile := filepath.Join(AppOutputDir(), "user_types.go")
	utWr, err := NewUserTypesWriter(utFile)
	if err != nil {
		panic(err) // bug
	}
	title := fmt.Sprintf("%s: Application User Types", api.Context())
	imports := []*codegen.ImportSpec{
		codegen.SimpleImport("github.com/goadesign/goa"),
		codegen.SimpleImport("fmt"),
		codegen.SimpleImport("time"),
	}
	utWr.WriteHeader(title, TargetPackage, imports)
	err = api.IterateUserTypes(func(t *design.UserTypeDefinition) error {
		return utWr.Execute(t)
	})
	g.genfiles = append(g.genfiles, utFile)
	if err != nil {
		return err
	}
	return utWr.FormatCode()
}
예제 #2
0
파일: generator.go 프로젝트: ajoulie/goa
func (g *Generator) generateClientResources(clientPkg string, funcs template.FuncMap, api *design.APIDefinition) error {
	userTypeTmpl := template.Must(template.New("userType").Funcs(funcs).Parse(userTypeTmpl))
	typeDecodeTmpl := template.Must(template.New("typeDecode").Funcs(funcs).Parse(typeDecodeTmpl))

	err := api.IterateResources(func(res *design.ResourceDefinition) error {
		return g.generateResourceClient(res, funcs)
	})
	if err != nil {
		return err
	}
	types := make(map[string]*design.UserTypeDefinition)
	for _, res := range api.Resources {
		for n, ut := range res.UserTypes() {
			types[n] = ut
		}
	}
	filename := filepath.Join(codegen.OutputDir, typesFileName+".go")
	file, err := codegen.SourceFileFor(filename)
	if err != nil {
		return err
	}
	imports := []*codegen.ImportSpec{
		codegen.SimpleImport("github.com/goadesign/goa"),
		codegen.SimpleImport("fmt"),
		codegen.SimpleImport("io"),
		codegen.SimpleImport("time"),
		codegen.NewImport("uuid", "github.com/satori/go.uuid"),
	}
	if err := file.WriteHeader("User Types", "client", imports); err != nil {
		return err
	}
	g.genfiles = append(g.genfiles, filename)

	// Generate user and media types used by action payloads and parameters
	err = api.IterateUserTypes(func(userType *design.UserTypeDefinition) error {
		if _, ok := g.generatedTypes[userType.TypeName]; ok {
			return nil
		}
		if _, ok := types[userType.TypeName]; ok {
			g.generatedTypes[userType.TypeName] = true
			return userTypeTmpl.Execute(file, userType)
		}
		return nil
	})
	if err != nil {
		return err
	}

	// Generate media types used by action responses and their load helpers
	err = api.IterateResources(func(res *design.ResourceDefinition) error {
		return res.IterateActions(func(a *design.ActionDefinition) error {
			return a.IterateResponses(func(r *design.ResponseDefinition) error {
				if mt := api.MediaTypeWithIdentifier(r.MediaType); mt != nil {
					if _, ok := g.generatedTypes[mt.TypeName]; !ok {
						g.generatedTypes[mt.TypeName] = true
						if !mt.IsBuiltIn() {
							if err := userTypeTmpl.Execute(file, mt); err != nil {
								return err
							}
						}
						typeName := mt.TypeName
						if mt.IsBuiltIn() {
							elems := strings.Split(typeName, ".")
							typeName = elems[len(elems)-1]
						}
						if err := typeDecodeTmpl.Execute(file, mt); err != nil {
							return err
						}
					}
				}
				return nil
			})
		})
	})
	if err != nil {
		return err
	}

	// Generate media types used in payloads but not in responses
	err = api.IterateMediaTypes(func(mediaType *design.MediaTypeDefinition) error {
		if mediaType.IsBuiltIn() {
			return nil
		}
		if _, ok := g.generatedTypes[mediaType.TypeName]; ok {
			return nil
		}
		if _, ok := types[mediaType.TypeName]; ok {
			g.generatedTypes[mediaType.TypeName] = true
			return userTypeTmpl.Execute(file, mediaType)
		}
		return nil
	})
	if err != nil {
		return err
	}

	return file.FormatCode()
}