goa_model_gen 0.9.2 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/goa_model_gen/cli.rb +13 -9
- data/lib/goa_model_gen/config.rb +16 -2
- data/lib/goa_model_gen/generator.rb +1 -0
- data/lib/goa_model_gen/go_package.rb +17 -0
- data/lib/goa_model_gen/go_struct.rb +4 -0
- data/lib/goa_model_gen/templates/converter.go.erb +6 -6
- data/lib/goa_model_gen/templates/goon.go.erb +1 -1
- data/lib/goa_model_gen/templates/store.go.erb +3 -3
- data/lib/goa_model_gen/templates/store_validation.go.erb +2 -2
- data/lib/goa_model_gen/templates/structs_main.go.erb +14 -2
- data/lib/goa_model_gen/type.rb +4 -0
- data/lib/goa_model_gen/version.rb +1 -1
- metadata +3 -3
- data/lib/goa_model_gen/templates/structs_base.go.erb +0 -170
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 282f36bc384d676a9b9162660234551dd1523af68efdd9084f488d4ee85a58c3
         | 
| 4 | 
            +
              data.tar.gz: fe886d206e933a280d498b76271e616a5e237658716693990c1d4773edd0152d
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: e35a1fe9ea39d9b73a0bb31c47a48f718403c9f33f7834ff5d5a22db908b930e8c4540b9931420912ed7b575c818e498a615d08d8bf8355aa75b74714845ae82
         | 
| 7 | 
            +
              data.tar.gz: 77a5e6431b7f9889cf4634680221d7896a1437d603f1ddbf2216bcc9bba9e6fe40102c1b05f120f96e1d06515f76f1fa1d0675c6f0a49a9b37e68e55c0b16621
         | 
    
        data/lib/goa_model_gen/cli.rb
    CHANGED
    
    | @@ -21,14 +21,20 @@ module GoaModelGen | |
| 21 21 | 
             
                class_option :force, type: :boolean, aliases: 'f', desc: 'Force overwrite files'
         | 
| 22 22 | 
             
                class_option :keep_editable, type: :boolean, aliases: 'k', default: true, desc: 'Keep user editable file'
         | 
| 23 23 | 
             
                class_option :log_level, type: :string, aliases: 'l', desc: 'Log level, one of  debug,info,warn,error,fatal. The default value is info'
         | 
| 24 | 
            -
                class_option :config, type: :string, aliases: 'c', default: ' | 
| 24 | 
            +
                class_option :config, type: :string, aliases: 'c', default: '.goa_model_gen.yaml', desc: 'Path to config file. You can generate it by config subcommand'
         | 
| 25 25 |  | 
| 26 | 
            -
                desc " | 
| 27 | 
            -
                def  | 
| 26 | 
            +
                desc "init", "Generate config file"
         | 
| 27 | 
            +
                def init(path = '.goa_model_gen.yaml')
         | 
| 28 28 | 
             
                  setup
         | 
| 29 29 | 
             
                  open(path, 'w'){|f| f.puts(Config.new.fulfill.to_yaml) }
         | 
| 30 30 | 
             
                end
         | 
| 31 31 |  | 
| 32 | 
            +
                desc "config", "Show configuration"
         | 
| 33 | 
            +
                def config(path = '.goa_model_gen.yaml')
         | 
| 34 | 
            +
                  setup
         | 
| 35 | 
            +
                  puts YAML.dump(cfg)
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 32 38 | 
             
                desc "show FILE1...", "Show model info from definition files"
         | 
| 33 39 | 
             
                def show(*paths)
         | 
| 34 40 | 
             
                  setup
         | 
| @@ -61,15 +67,14 @@ module GoaModelGen | |
| 61 67 | 
             
                  })
         | 
| 62 68 | 
             
                  load_types_for(paths) do |source_file|
         | 
| 63 69 | 
             
                    source_file.types.select(&:store?).each do |model|
         | 
| 64 | 
            -
                      basename = model.name.underscore
         | 
| 65 70 | 
             
                      variables = {
         | 
| 66 71 | 
             
                        model: model,
         | 
| 67 | 
            -
                         | 
| 72 | 
            +
                        model_package: model.package,
         | 
| 68 73 | 
             
                      }
         | 
| 69 74 |  | 
| 70 75 | 
             
                      new_generator.tap{|g| g.source_file = source_file }.process({
         | 
| 71 | 
            -
                        'templates/store.go.erb' => File.join(cfg.store_dir,  | 
| 72 | 
            -
                        'templates/store_validation.go.erb' => File.join(cfg.store_dir,  | 
| 76 | 
            +
                        'templates/store.go.erb' => File.join(cfg.store_dir, model.package_path_name, "store.go"),
         | 
| 77 | 
            +
                        'templates/store_validation.go.erb' => File.join(cfg.store_dir, model.package_path_name, "validation.go"),
         | 
| 73 78 | 
             
                      }, variables)
         | 
| 74 79 | 
             
                    end
         | 
| 75 80 | 
             
                  end
         | 
| @@ -79,7 +84,6 @@ module GoaModelGen | |
| 79 84 | 
             
                def structs_gen
         | 
| 80 85 | 
             
                  setup
         | 
| 81 86 | 
             
                  new_generator.process({
         | 
| 82 | 
            -
                    "templates/structs_base.go.erb" => File.join(cfg.structs_gen_dir, "structs.go"),
         | 
| 83 87 | 
             
                    "templates/structs_main.go.erb" => File.join(cfg.structs_gen_dir, "main.go"),
         | 
| 84 88 | 
             
                  })
         | 
| 85 89 | 
             
                end
         | 
| @@ -103,7 +107,7 @@ module GoaModelGen | |
| 103 107 | 
             
                      payload: pt ? GoStruct.new(pt) : nil,
         | 
| 104 108 | 
             
                      result: rt ? GoStruct.new(rt) : nil,
         | 
| 105 109 | 
             
                    }
         | 
| 106 | 
            -
                    new_generator.run('templates/converter.go.erb', File.join(cfg.converter_dir, m. | 
| 110 | 
            +
                    new_generator.run('templates/converter.go.erb', File.join(cfg.converter_dir, m.package_path_name, "conv.go"), variables)
         | 
| 107 111 | 
             
                  end
         | 
| 108 112 | 
             
                end
         | 
| 109 113 |  | 
    
        data/lib/goa_model_gen/config.rb
    CHANGED
    
    | @@ -10,12 +10,17 @@ module GoaModelGen | |
| 10 10 | 
             
              class Config
         | 
| 11 11 |  | 
| 12 12 | 
             
                ATTRIBUTES = %w[
         | 
| 13 | 
            -
                  go_package
         | 
| 14 13 | 
             
                  swagger_yaml
         | 
| 15 14 | 
             
                  gofmt_disabled
         | 
| 15 | 
            +
                  base_package_path
         | 
| 16 16 | 
             
                  model_dir
         | 
| 17 | 
            +
                  model_package_path
         | 
| 17 18 | 
             
                  store_dir
         | 
| 19 | 
            +
                  store_package_path
         | 
| 18 20 | 
             
                  converter_dir
         | 
| 21 | 
            +
                  converter_package_path
         | 
| 22 | 
            +
                  goa_gen_dir
         | 
| 23 | 
            +
                  goa_gen_package_path
         | 
| 19 24 | 
             
                  structs_gen_dir
         | 
| 20 25 | 
             
                  validator_path
         | 
| 21 26 | 
             
                  generator_version_comment
         | 
| @@ -24,12 +29,17 @@ module GoaModelGen | |
| 24 29 | 
             
                attr_accessor *ATTRIBUTES
         | 
| 25 30 |  | 
| 26 31 | 
             
                def fulfill
         | 
| 27 | 
            -
                  @go_package     ||= default_go_package
         | 
| 28 32 | 
             
                  # @swagger_yaml   ||= "./swagger/swagger.yaml"
         | 
| 29 33 | 
             
                  @gofmt_disabled ||= false
         | 
| 30 34 | 
             
                  @model_dir      ||= "./model"
         | 
| 31 35 | 
             
                  @store_dir      ||= "./stores"
         | 
| 32 36 | 
             
                  @converter_dir  ||= "./converters"
         | 
| 37 | 
            +
                  @goa_gen_dir    ||= "./gen"
         | 
| 38 | 
            +
                  @base_package_path  ||= default_go_package
         | 
| 39 | 
            +
                  @model_package_path ||= join_paths(@base_package_path, @model_dir)
         | 
| 40 | 
            +
                  @store_package_path ||= join_paths(@base_package_path, @store_dir)
         | 
| 41 | 
            +
                  @converter_package_path ||= join_paths(@base_package_path, @converter_dir)
         | 
| 42 | 
            +
                  @goa_gen_package_path   ||= join_paths(@base_package_path, @goa_gen_dir)
         | 
| 33 43 | 
             
                  @structs_gen_dir ||= "./cmd/structs"
         | 
| 34 44 | 
             
                  @validator_path ||= "gopkg.in/go-playground/validator.v9"
         | 
| 35 45 | 
             
                  @generator_version_comment ||= false
         | 
| @@ -70,5 +80,9 @@ module GoaModelGen | |
| 70 80 | 
             
                  return Pathname.new(Dir.pwd).relative_path_from(Pathname.new(File.join(gopath, "src"))).to_s
         | 
| 71 81 | 
             
                end
         | 
| 72 82 |  | 
| 83 | 
            +
                def join_paths(path1, path2)
         | 
| 84 | 
            +
                  Pathname.new(path1).join(Pathname.new(path2)).to_s
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
             | 
| 73 87 | 
             
              end
         | 
| 74 88 | 
             
            end
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            require "goa_model_gen"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module GoaModelGen
         | 
| 4 | 
            +
              module GoPackage
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                # goa allows underscore for file name
         | 
| 7 | 
            +
                def package_path_name
         | 
| 8 | 
            +
                  name.underscore
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                # underscore isn't used for go package name
         | 
| 12 | 
            +
                def package
         | 
| 13 | 
            +
                  name.downcase.gsub('_', '')
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
            end
         | 
| @@ -1,10 +1,14 @@ | |
| 1 1 | 
             
            # coding: utf-8
         | 
| 2 2 | 
             
            require 'goa_model_gen'
         | 
| 3 3 |  | 
| 4 | 
            +
            require "goa_model_gen/go_package"
         | 
| 5 | 
            +
             | 
| 4 6 | 
             
            require "active_support/core_ext/string"
         | 
| 5 7 |  | 
| 6 8 | 
             
            module GoaModelGen
         | 
| 7 9 | 
             
              class GoStruct
         | 
| 10 | 
            +
                include GoPackage
         | 
| 11 | 
            +
             | 
| 8 12 | 
             
                attr_reader :name, :pkg_path, :size, :fields
         | 
| 9 13 | 
             
                def initialize(d)
         | 
| 10 14 | 
             
                  @name = d['Name']
         | 
| @@ -7,16 +7,16 @@ def method_calling_exp(m, argument) | |
| 7 7 | 
             
              end
         | 
| 8 8 | 
             
            end
         | 
| 9 9 |  | 
| 10 | 
            -
            gen_package = "#{config. | 
| 10 | 
            +
            gen_package = "#{config.goa_gen_package_path}/#{model.package_path_name}"
         | 
| 11 11 |  | 
| 12 12 | 
             
            -%>
         | 
| 13 | 
            -
            <%- package model. | 
| 13 | 
            +
            <%- package model.package -%>
         | 
| 14 14 |  | 
| 15 15 | 
             
            <%- if payload-%>
         | 
| 16 16 | 
             
            <%-
         | 
| 17 | 
            -
                	import "#{config.go_package}/converters"
         | 
| 18 17 | 
             
            			import :gen, gen_package
         | 
| 19 | 
            -
            			import  | 
| 18 | 
            +
            			import config.converter_package_path
         | 
| 19 | 
            +
            			import config.model_package_path
         | 
| 20 20 | 
             
            -%>
         | 
| 21 21 | 
             
            func <%= model.name %>PayloadToModel(payload *gen.<%= payload.name %>) (*model.<%= model.name %>, error) {
         | 
| 22 22 | 
             
            	m := &model.<%= model.name %>{}
         | 
| @@ -82,9 +82,9 @@ func CopyFrom<%= model.name %>PayloadToModel(payload *gen.<%= payload.name %>, m | |
| 82 82 |  | 
| 83 83 | 
             
            <%- if result -%>
         | 
| 84 84 | 
             
            <%-
         | 
| 85 | 
            -
                	import "#{config.go_package}/converters"
         | 
| 86 85 | 
             
            			import :gen, gen_package
         | 
| 87 | 
            -
            			import  | 
| 86 | 
            +
            			import config.converter_package_path
         | 
| 87 | 
            +
            			import config.model_package_path
         | 
| 88 88 |  | 
| 89 89 | 
             
                  indirect_types =
         | 
| 90 90 | 
             
                    result.fields.map{|rf| rf.type.pkg_path == gen_package ? rf.type : nil }.
         | 
| @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            <%- package  | 
| 1 | 
            +
            <%- package model_package -%>
         | 
| 2 2 |  | 
| 3 3 | 
             
            <%-	 store_name = "#{model.name}Store" -%>
         | 
| 4 4 | 
             
            <%-
         | 
| @@ -6,8 +6,8 @@ | |
| 6 6 | 
             
            			import "fmt"
         | 
| 7 7 | 
             
            			import "google.golang.org/appengine/datastore"
         | 
| 8 8 | 
             
            			import "google.golang.org/appengine/log"
         | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 9 | 
            +
            			import config.model_package_path
         | 
| 10 | 
            +
            			import :goon, "#{config.store_package_path}/goon_store"
         | 
| 11 11 |  | 
| 12 12 | 
             
                  model_name = "model.#{model.name}"
         | 
| 13 13 | 
             
            -%>
         | 
| @@ -1,9 +1,9 @@ | |
| 1 1 | 
             
            <%- user_editable -%>
         | 
| 2 | 
            -
            <%- package  | 
| 2 | 
            +
            <%- package model_package -%>
         | 
| 3 3 |  | 
| 4 4 | 
             
            <%-
         | 
| 5 5 | 
             
                  import "context"
         | 
| 6 | 
            -
             | 
| 6 | 
            +
            			import config.model_package_path
         | 
| 7 7 | 
             
            -%>
         | 
| 8 8 | 
             
            <%-   store_name = "#{model.name}Store" -%>
         | 
| 9 9 | 
             
            func (s *<%= store_name %>) Validate(ctx context.Context, m *model.<%= model.name %>) error {
         | 
| @@ -3,14 +3,21 @@ package 'main' | |
| 3 3 |  | 
| 4 4 | 
             
            user_editable
         | 
| 5 5 |  | 
| 6 | 
            +
            import "os"
         | 
| 7 | 
            +
            import "reflect"
         | 
| 6 8 | 
             
            import "regexp"
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            import "github.com/akm/typedict"
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            import config.model_package_path
         | 
| 7 13 | 
             
            -%>
         | 
| 8 14 |  | 
| 15 | 
            +
             | 
| 9 16 | 
             
            // Usage
         | 
| 10 17 | 
             
            // $ go run <%= config.structs_gen_dir %>/*.go
         | 
| 11 18 |  | 
| 12 19 | 
             
            func main() {
         | 
| 13 | 
            -
            	ptn := regexp.MustCompile(`\A<%= config. | 
| 20 | 
            +
            	ptn := regexp.MustCompile(`\A<%= config.model_package_path %>|\A<%= config.store_package_path %>|\A<%= config.converter_package_path %>`)
         | 
| 14 21 |  | 
| 15 22 | 
             
            	objectMap := map[string][]interface{}{
         | 
| 16 23 | 
             
            		"model": []interface{}{
         | 
| @@ -24,5 +31,10 @@ func main() { | |
| 24 31 | 
             
            		},
         | 
| 25 32 | 
             
            	}
         | 
| 26 33 |  | 
| 27 | 
            -
            	 | 
| 34 | 
            +
            	structs := typedict.CategorizedTypes(objectMap,
         | 
| 35 | 
            +
            		typedict.KindFilter(append([]reflect.Kind{reflect.Struct}, typedict.SimpleKinds...)...),
         | 
| 36 | 
            +
            		func(t reflect.Type) bool {
         | 
| 37 | 
            +
            			return ptn.MatchString(t.PkgPath())
         | 
| 38 | 
            +
            		})
         | 
| 39 | 
            +
            	typedict.WriteJson(os.Stdout, structs)
         | 
| 28 40 | 
             
            }
         | 
    
        data/lib/goa_model_gen/type.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: goa_model_gen
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.9. | 
| 4 | 
            +
              version: 0.9.3
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - akm
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2019-02- | 
| 11 | 
            +
            date: 2019-02-21 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: thor
         | 
| @@ -147,6 +147,7 @@ files: | |
| 147 147 | 
             
            - lib/goa_model_gen/config.rb
         | 
| 148 148 | 
             
            - lib/goa_model_gen/field.rb
         | 
| 149 149 | 
             
            - lib/goa_model_gen/generator.rb
         | 
| 150 | 
            +
            - lib/goa_model_gen/go_package.rb
         | 
| 150 151 | 
             
            - lib/goa_model_gen/go_struct.rb
         | 
| 151 152 | 
             
            - lib/goa_model_gen/goa.rb
         | 
| 152 153 | 
             
            - lib/goa_model_gen/golang_helper.rb
         | 
| @@ -162,7 +163,6 @@ files: | |
| 162 163 | 
             
            - lib/goa_model_gen/templates/model_validation.go.erb
         | 
| 163 164 | 
             
            - lib/goa_model_gen/templates/store.go.erb
         | 
| 164 165 | 
             
            - lib/goa_model_gen/templates/store_validation.go.erb
         | 
| 165 | 
            -
            - lib/goa_model_gen/templates/structs_base.go.erb
         | 
| 166 166 | 
             
            - lib/goa_model_gen/templates/structs_main.go.erb
         | 
| 167 167 | 
             
            - lib/goa_model_gen/templates/validator.go.erb
         | 
| 168 168 | 
             
            - lib/goa_model_gen/type.rb
         | 
| @@ -1,170 +0,0 @@ | |
| 1 | 
            -
            <%- package 'main' -%>
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            import (
         | 
| 4 | 
            -
            	"encoding/json"
         | 
| 5 | 
            -
            	"fmt"
         | 
| 6 | 
            -
            	"os"
         | 
| 7 | 
            -
            	"reflect"
         | 
| 8 | 
            -
            	"regexp"
         | 
| 9 | 
            -
            	"sort"
         | 
| 10 | 
            -
            )
         | 
| 11 | 
            -
             | 
| 12 | 
            -
            func process(objectMap map[string][]interface{}, ptn *regexp.Regexp) {
         | 
| 13 | 
            -
            	res := map[string][]*DataType{}
         | 
| 14 | 
            -
             | 
| 15 | 
            -
            	for key, objects := range objectMap {
         | 
| 16 | 
            -
            		types := []reflect.Type{}
         | 
| 17 | 
            -
            		for _, obj := range objects {
         | 
| 18 | 
            -
            			types = append(types, reflect.TypeOf(obj))
         | 
| 19 | 
            -
            		}
         | 
| 20 | 
            -
             | 
| 21 | 
            -
            		types = digTypes(types)
         | 
| 22 | 
            -
             | 
| 23 | 
            -
            		dataTypes := []*DataType{}
         | 
| 24 | 
            -
            		for _, t := range types {
         | 
| 25 | 
            -
            			dt := newDataType(t)
         | 
| 26 | 
            -
            			if ptn.MatchString(dt.PkgPath) {
         | 
| 27 | 
            -
            				dataTypes = append(dataTypes, dt)
         | 
| 28 | 
            -
            			}
         | 
| 29 | 
            -
            		}
         | 
| 30 | 
            -
             | 
| 31 | 
            -
            		sort.Slice(dataTypes, func(i, j int) bool {
         | 
| 32 | 
            -
            			return (dataTypes[i].PkgPath +"."+ dataTypes[i].Name) < (dataTypes[j].PkgPath +"."+ dataTypes[j].Name)
         | 
| 33 | 
            -
            		})
         | 
| 34 | 
            -
             | 
| 35 | 
            -
            		res[key] = dataTypes
         | 
| 36 | 
            -
            	}
         | 
| 37 | 
            -
             | 
| 38 | 
            -
            	b, err := json.MarshalIndent(res, "", "  ")
         | 
| 39 | 
            -
            	if err != nil {
         | 
| 40 | 
            -
            		fmt.Fprintf(os.Stderr, "Failed to json.MarshalIndent because of %v\n", err)
         | 
| 41 | 
            -
            		return
         | 
| 42 | 
            -
            	}
         | 
| 43 | 
            -
            	_, err = os.Stdout.Write(b)
         | 
| 44 | 
            -
            	if err != nil {
         | 
| 45 | 
            -
            		fmt.Fprintf(os.Stderr, "Failed to write because of %v\n", err)
         | 
| 46 | 
            -
            		return
         | 
| 47 | 
            -
            	}
         | 
| 48 | 
            -
            }
         | 
| 49 | 
            -
             | 
| 50 | 
            -
            type DataFieldType struct {
         | 
| 51 | 
            -
            	PkgPath        string   `json:"PkgPath,omitempty"`
         | 
| 52 | 
            -
            	Name           string   `json:"Name,omitempty"`
         | 
| 53 | 
            -
            	Kinds          []string `json:"Kinds,omitempty"`
         | 
| 54 | 
            -
            	Representation string
         | 
| 55 | 
            -
            }
         | 
| 56 | 
            -
             | 
| 57 | 
            -
            type DataField struct {
         | 
| 58 | 
            -
            	Name      string
         | 
| 59 | 
            -
            	Type      *DataFieldType
         | 
| 60 | 
            -
            	RawTag    string            `json:"RawTag,omitempty"`
         | 
| 61 | 
            -
            	Tag       map[string]string `json:"Tag,omitempty"`
         | 
| 62 | 
            -
            	Anonymous bool
         | 
| 63 | 
            -
            }
         | 
| 64 | 
            -
             | 
| 65 | 
            -
            type DataType struct {
         | 
| 66 | 
            -
            	Name    string
         | 
| 67 | 
            -
            	PkgPath string
         | 
| 68 | 
            -
            	Size    uintptr
         | 
| 69 | 
            -
            	Fields  []*DataField
         | 
| 70 | 
            -
            }
         | 
| 71 | 
            -
             | 
| 72 | 
            -
            func digTypes(types []reflect.Type) []reflect.Type {
         | 
| 73 | 
            -
            	m := map[string]reflect.Type{}
         | 
| 74 | 
            -
            	for _, t := range types {
         | 
| 75 | 
            -
            		key := t.PkgPath() + "." + t.Name()
         | 
| 76 | 
            -
            		m[key] = t
         | 
| 77 | 
            -
            	}
         | 
| 78 | 
            -
             | 
| 79 | 
            -
            	for _, t := range types {
         | 
| 80 | 
            -
            		digType(m, t)
         | 
| 81 | 
            -
            	}
         | 
| 82 | 
            -
             | 
| 83 | 
            -
            	r := []reflect.Type{}
         | 
| 84 | 
            -
            	for _, t := range m {
         | 
| 85 | 
            -
            		r = append(r, t)
         | 
| 86 | 
            -
            	}
         | 
| 87 | 
            -
            	return r
         | 
| 88 | 
            -
            }
         | 
| 89 | 
            -
             | 
| 90 | 
            -
            func digType(m map[string]reflect.Type, t reflect.Type) {
         | 
| 91 | 
            -
            	switch t.Kind() {
         | 
| 92 | 
            -
            	case reflect.Struct:
         | 
| 93 | 
            -
            		digStruct(m, t)
         | 
| 94 | 
            -
            	case reflect.Array, reflect.Chan, reflect.Map, reflect.Ptr, reflect.Slice:
         | 
| 95 | 
            -
            		digType(m, t.Elem())
         | 
| 96 | 
            -
            	}
         | 
| 97 | 
            -
            }
         | 
| 98 | 
            -
             | 
| 99 | 
            -
            func digStruct(m map[string]reflect.Type, t reflect.Type) {
         | 
| 100 | 
            -
            	numField := t.NumField()
         | 
| 101 | 
            -
            	for i := 0; i < numField; i++ {
         | 
| 102 | 
            -
            		f := t.Field(i)
         | 
| 103 | 
            -
            		ft := f.Type
         | 
| 104 | 
            -
            		if ft.PkgPath() != "" {
         | 
| 105 | 
            -
            			key := ft.PkgPath() + "." + ft.Name()
         | 
| 106 | 
            -
            			_, ok := m[key]
         | 
| 107 | 
            -
            			if !ok {
         | 
| 108 | 
            -
            				m[key] = ft
         | 
| 109 | 
            -
            				switch ft.Kind() {
         | 
| 110 | 
            -
            				case reflect.Struct:
         | 
| 111 | 
            -
            					digType(m, ft)
         | 
| 112 | 
            -
            				}
         | 
| 113 | 
            -
            			}
         | 
| 114 | 
            -
            		}
         | 
| 115 | 
            -
            	}
         | 
| 116 | 
            -
            }
         | 
| 117 | 
            -
             | 
| 118 | 
            -
            func newDataType(t reflect.Type) *DataType {
         | 
| 119 | 
            -
            	r := &DataType{
         | 
| 120 | 
            -
            		Name:    t.Name(),
         | 
| 121 | 
            -
            		PkgPath: t.PkgPath(),
         | 
| 122 | 
            -
            		Size:    t.Size(),
         | 
| 123 | 
            -
            	}
         | 
| 124 | 
            -
            	if t.Kind() != reflect.Struct {
         | 
| 125 | 
            -
            		return r
         | 
| 126 | 
            -
            	}
         | 
| 127 | 
            -
             | 
| 128 | 
            -
            	fields := []*DataField{}
         | 
| 129 | 
            -
            	numField := t.NumField()
         | 
| 130 | 
            -
            	for i := 0; i < numField; i++ {
         | 
| 131 | 
            -
            		f := t.Field(i)
         | 
| 132 | 
            -
            		ft := f.Type
         | 
| 133 | 
            -
            		fields = append(fields, &DataField{
         | 
| 134 | 
            -
            			Name:      f.Name,
         | 
| 135 | 
            -
            			Anonymous: f.Anonymous,
         | 
| 136 | 
            -
            			Type:      DataFieldTypeFromType(ft),
         | 
| 137 | 
            -
            			Tag:       parseTag(string(f.Tag)),
         | 
| 138 | 
            -
            			RawTag:    string(f.Tag),
         | 
| 139 | 
            -
            		})
         | 
| 140 | 
            -
            	}
         | 
| 141 | 
            -
            	r.Fields = fields
         | 
| 142 | 
            -
            	return r
         | 
| 143 | 
            -
            }
         | 
| 144 | 
            -
             | 
| 145 | 
            -
            func DataFieldTypeFromType(t reflect.Type) *DataFieldType {
         | 
| 146 | 
            -
            	switch t.Kind() {
         | 
| 147 | 
            -
            	case reflect.Array, reflect.Chan, reflect.Map, reflect.Ptr, reflect.Slice:
         | 
| 148 | 
            -
            		r := DataFieldTypeFromType(t.Elem())
         | 
| 149 | 
            -
            		r.Kinds = append(r.Kinds, t.Kind().String())
         | 
| 150 | 
            -
            		return r
         | 
| 151 | 
            -
            	default:
         | 
| 152 | 
            -
            		return &DataFieldType{
         | 
| 153 | 
            -
            			PkgPath:        t.PkgPath(),
         | 
| 154 | 
            -
            			Name:           t.Name(),
         | 
| 155 | 
            -
            			Kinds:          []string{t.Kind().String()},
         | 
| 156 | 
            -
            			Representation: t.String(),
         | 
| 157 | 
            -
            		}
         | 
| 158 | 
            -
            	}
         | 
| 159 | 
            -
            }
         | 
| 160 | 
            -
             | 
| 161 | 
            -
            var TagParserRE = regexp.MustCompile(`\s*([^:\s]+?):"(.+?)"`)
         | 
| 162 | 
            -
             | 
| 163 | 
            -
            func parseTag(src string) map[string]string {
         | 
| 164 | 
            -
            	parsed := TagParserRE.FindAllStringSubmatch(src, -1)
         | 
| 165 | 
            -
            	r := map[string]string{}
         | 
| 166 | 
            -
            	for _, parts := range parsed {
         | 
| 167 | 
            -
            		r[parts[1]] = parts[2]
         | 
| 168 | 
            -
            	}
         | 
| 169 | 
            -
            	return r
         | 
| 170 | 
            -
            }
         |