goon_model_gen 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/goon_model_gen/builder/converter_builder.rb +76 -0
- data/lib/goon_model_gen/cli.rb +24 -0
- data/lib/goon_model_gen/config.rb +4 -0
- data/lib/goon_model_gen/converter/abstract_conv.rb +20 -0
- data/lib/goon_model_gen/converter/conv_file.rb +20 -0
- data/lib/goon_model_gen/converter/loader.rb +85 -0
- data/lib/goon_model_gen/converter/mapping.rb +21 -0
- data/lib/goon_model_gen/converter/payload_conv.rb +25 -0
- data/lib/goon_model_gen/converter/result_conv.rb +24 -0
- data/lib/goon_model_gen/converter/type_ref.rb +14 -0
- data/lib/goon_model_gen/golang/builtin.rb +2 -1
- data/lib/goon_model_gen/golang/combination_type.rb +45 -0
- data/lib/goon_model_gen/golang/enum.rb +1 -1
- data/lib/goon_model_gen/golang/field.rb +51 -0
- data/lib/goon_model_gen/golang/file.rb +3 -4
- data/lib/goon_model_gen/golang/modifier.rb +4 -2
- data/lib/goon_model_gen/golang/named_slice.rb +12 -2
- data/lib/goon_model_gen/golang/package.rb +25 -5
- data/lib/goon_model_gen/golang/packages.rb +69 -17
- data/lib/goon_model_gen/golang/structs_loader.rb +67 -0
- data/lib/goon_model_gen/golang/type.rb +4 -2
- data/lib/goon_model_gen/templates/converter/payload/01_base_imports.go.erb +11 -0
- data/lib/goon_model_gen/templates/converter/payload/02_SliceToModelSlice.go.erb +45 -0
- data/lib/goon_model_gen/templates/converter/payload/03_ToModel.go.erb +21 -0
- data/lib/goon_model_gen/templates/converter/payload/04_AssignModel.go.erb +90 -0
- data/lib/goon_model_gen/templates/converter/result/01_base_imports.go.erb +18 -0
- data/lib/goon_model_gen/templates/converter/result/02_SliceToResultSlice.go.erb +33 -0
- data/lib/goon_model_gen/templates/converter/result/03_ToResult.go.erb +50 -0
- data/lib/goon_model_gen/version.rb +1 -1
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4283b78918a93a63233070c2e5d0d1ef100d4b214e672b50640f5b70c6aa08b3
|
4
|
+
data.tar.gz: f0bc7f7a08b1311a4b12d754d1bce760fbe59ac39e6bdbf48e215d63c3b9cf2e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26af49ba18494c6722cd7421ab53598c70ad86a8ced5269ea1328989713678517f696f4886b6cac1fdad5c378e230d72a34e3c0cc399a0db04f7973a1227fb80
|
7
|
+
data.tar.gz: ad98807c4bfdfbf715b2b528ae5b193b3e205489d505ddca16956c74132113ef50329a8526aef636dff16498b25308a6c02a0f6710a6740488ee0d88b95e576f
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require "goon_model_gen"
|
2
|
+
|
3
|
+
require "goon_model_gen/builder/abstract_builder"
|
4
|
+
|
5
|
+
require "goon_model_gen/source/struct"
|
6
|
+
|
7
|
+
require "goon_model_gen/golang/package"
|
8
|
+
require "goon_model_gen/golang/datastore_supported"
|
9
|
+
|
10
|
+
|
11
|
+
module GoonModelGen
|
12
|
+
module Builder
|
13
|
+
class ConverterBuilder < AbstractBuilder
|
14
|
+
attr_reader :loader
|
15
|
+
attr_reader :packages
|
16
|
+
|
17
|
+
# @param base_package_path [String]
|
18
|
+
# @param loader [Converter::Loader]
|
19
|
+
# @param packages [Golang::Packages]
|
20
|
+
def initialize(base_package_path, loader, packages)
|
21
|
+
super(base_package_path)
|
22
|
+
@package_suffix = "_conv"
|
23
|
+
@loader = loader
|
24
|
+
@packages = packages
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param conv_file_path [Array<String>]
|
28
|
+
def build(conv_file_paths)
|
29
|
+
Golang::Packages.new.tap do |pkgs|
|
30
|
+
build_sentences = []
|
31
|
+
conv_file_paths.each do |conv_file_path|
|
32
|
+
conf_file = loader.process(conv_file_path)
|
33
|
+
procs = build_package(pkgs, conf_file)
|
34
|
+
build_sentences.concat(procs)
|
35
|
+
end
|
36
|
+
resolve_type_names(pkgs)
|
37
|
+
build_sentences.each(&:call)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param pkgs [Golang::Packages]
|
42
|
+
# @param conv_file [Converter::ConvFile]
|
43
|
+
# @return [Array<Proc>]
|
44
|
+
def build_package(pkgs, conv_file)
|
45
|
+
procs = []
|
46
|
+
pkgs.new_package(conv_file.converter_package_path).tap do |pkg|
|
47
|
+
{
|
48
|
+
'converter/payload' => conv_file.payload_convs,
|
49
|
+
'converter/result' => conv_file.result_convs,
|
50
|
+
}.each do |template_dir, convs|
|
51
|
+
convs.each do |conv|
|
52
|
+
conv_type = pkg.new_combination_type(conv.name).tap do |t|
|
53
|
+
m = conv.model
|
54
|
+
g = conv.gen_type
|
55
|
+
t.add(:model, m.name, m.package_path, m.package_base_path)
|
56
|
+
t.add(:gen_type, g.name, g.package_path, g.package_base_path)
|
57
|
+
t.memo['mappings'] = conv.mappings
|
58
|
+
unless conv.model.slice_with_ptr.nil?
|
59
|
+
t.memo['model_slice_with_ptr'] = conv.model.slice_with_ptr
|
60
|
+
end
|
61
|
+
end
|
62
|
+
procs << Proc.new{ build_sentences_with(template_dir, conv_type, nil) }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
return procs
|
67
|
+
end
|
68
|
+
|
69
|
+
# @param pkgs [Golang::Packages]
|
70
|
+
def resolve_type_names(pkgs)
|
71
|
+
pkgs.resolve_type_names(Golang::DatastoreSupported.packages.dup.add(packages))
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/goon_model_gen/cli.rb
CHANGED
@@ -8,7 +8,10 @@ require "goon_model_gen/config"
|
|
8
8
|
require "goon_model_gen/builder/model_builder"
|
9
9
|
require "goon_model_gen/builder/store_builder"
|
10
10
|
require "goon_model_gen/builder/validation_builder"
|
11
|
+
require "goon_model_gen/builder/converter_builder"
|
12
|
+
require "goon_model_gen/converter/loader"
|
11
13
|
require "goon_model_gen/source/loader"
|
14
|
+
require "goon_model_gen/golang/structs_loader"
|
12
15
|
require "goon_model_gen/generator"
|
13
16
|
|
14
17
|
module GoonModelGen
|
@@ -58,6 +61,27 @@ module GoonModelGen
|
|
58
61
|
end
|
59
62
|
end
|
60
63
|
|
64
|
+
desc "converter FILE1...", "Generate store files from converter YAML files"
|
65
|
+
option :inspect, type: :boolean, desc: "Don't generate any file and show package objects if given"
|
66
|
+
def converter(*paths)
|
67
|
+
loader = Converter::Loader.new(cfg)
|
68
|
+
package_hash = Golang::StructsLoader.new.process(cfg.structs_json_path) # Golang::Packages
|
69
|
+
packages = Golang::Packages.wrap(package_hash.values.flatten)
|
70
|
+
converter_package = packages.find_or_new(cfg.converter_package_path)
|
71
|
+
|
72
|
+
b = Builder::ConverterBuilder.new(cfg.converter_package_path, loader, Golang::Packages.new.add(*packages))
|
73
|
+
conv_packages = b.build(paths)
|
74
|
+
|
75
|
+
if options[:inspect]
|
76
|
+
puts YAML.dump(conv_packages)
|
77
|
+
else
|
78
|
+
conv_packages.map(&:files).flatten.each do |f|
|
79
|
+
new_generator(f, packages).
|
80
|
+
run(converter_package: converter_package)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
61
85
|
no_commands do
|
62
86
|
def cfg
|
63
87
|
@cfg ||= Config.new.load_from(options[:config])
|
@@ -20,7 +20,10 @@ module GoonModelGen
|
|
20
20
|
store_package_path
|
21
21
|
converter_dir
|
22
22
|
converter_package_path
|
23
|
+
goa_gen_dir
|
24
|
+
goa_gen_package_path
|
23
25
|
structs_gen_dir
|
26
|
+
structs_json_path
|
24
27
|
validator_package_path
|
25
28
|
version_comment
|
26
29
|
].freeze
|
@@ -41,6 +44,7 @@ module GoonModelGen
|
|
41
44
|
@converter_package_path ||= join_paths(@base_package_path, @converter_dir)
|
42
45
|
@goa_gen_package_path ||= join_paths(@base_package_path, @goa_gen_dir)
|
43
46
|
@structs_gen_dir ||= "./cmd/structs"
|
47
|
+
@structs_json_path ||= "./structs.json"
|
44
48
|
@version_comment ||= false
|
45
49
|
self
|
46
50
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "goon_model_gen"
|
2
|
+
|
3
|
+
module GoonModelGen
|
4
|
+
module Converter
|
5
|
+
class AbstractConv
|
6
|
+
attr_accessor :file # ConvFile
|
7
|
+
attr_reader :name
|
8
|
+
attr_reader :model # TypeRef
|
9
|
+
attr_reader :gen_type # TypeRef Payload/Result
|
10
|
+
attr_reader :mappings
|
11
|
+
|
12
|
+
def initialize(name, model, gen_type, mappings)
|
13
|
+
@name = name
|
14
|
+
@model = model
|
15
|
+
@gen_type = gen_type
|
16
|
+
@mappings = mappings
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "goon_model_gen"
|
2
|
+
|
3
|
+
module GoonModelGen
|
4
|
+
module Converter
|
5
|
+
class ConvFile
|
6
|
+
attr_reader :path
|
7
|
+
attr_reader :converter_package_path # String
|
8
|
+
attr_accessor :payload_convs, :result_convs # [XxxxConv]
|
9
|
+
|
10
|
+
def initialize(path, converter_package_path)
|
11
|
+
@path = path
|
12
|
+
@converter_package_path = converter_package_path
|
13
|
+
end
|
14
|
+
|
15
|
+
def basename
|
16
|
+
::File.basename(path, '.*')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require "goon_model_gen"
|
2
|
+
|
3
|
+
require "erb"
|
4
|
+
require "yaml"
|
5
|
+
|
6
|
+
require "goon_model_gen/converter/conv_file"
|
7
|
+
require "goon_model_gen/converter/payload_conv"
|
8
|
+
require "goon_model_gen/converter/result_conv"
|
9
|
+
require "goon_model_gen/converter/type_ref"
|
10
|
+
require "goon_model_gen/converter/mapping"
|
11
|
+
|
12
|
+
require "active_support/core_ext/string"
|
13
|
+
|
14
|
+
module GoonModelGen
|
15
|
+
module Converter
|
16
|
+
class Loader
|
17
|
+
attr_reader :config
|
18
|
+
|
19
|
+
def initialize(config)
|
20
|
+
@config = config
|
21
|
+
end
|
22
|
+
|
23
|
+
def process(path)
|
24
|
+
erb = ERB.new(::File.read(path), nil, "-")
|
25
|
+
erb.filename = path
|
26
|
+
txt = erb.result
|
27
|
+
raw = YAML.load(txt)
|
28
|
+
|
29
|
+
converter_dir = raw['converter_dir'] || ::File.basename(path, '.*')
|
30
|
+
converter_package_path = raw['converter_package_path'] || File.join(config.converter_package_path, converter_dir)
|
31
|
+
ConvFile.new(path, converter_package_path).tap do |f|
|
32
|
+
f.payload_convs = load_conv_defs(f, PayloadConv, raw['payloads'] || {})
|
33
|
+
f.result_convs = load_conv_defs(f, ResultConv, raw['results'] || {})
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def load_conv_defs(f, conv_class, hash)
|
38
|
+
hash.map do |(name, definition)|
|
39
|
+
model = load_model_for_conv(definition['model'])
|
40
|
+
gen_type = TypeRef.new(name, File.join(config.goa_gen_package_path, f.basename))
|
41
|
+
mappings = load_mappings(definition['mappings'], conv_class)
|
42
|
+
conv_class.new(name, model, gen_type, mappings).tap do |conv|
|
43
|
+
conv.file = f
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def load_model_for_conv(obj)
|
49
|
+
pkg_name, pkg_path, pkg_base_path = nil, nil, nil
|
50
|
+
slice_with_ptr = nil
|
51
|
+
case obj
|
52
|
+
when Hash
|
53
|
+
pkg_name, pkg_path = obj['name'], obj['package_path']
|
54
|
+
slice_with_ptr = obj['slice_with_ptr']
|
55
|
+
when String
|
56
|
+
pkg_name = obj
|
57
|
+
pkg_base_path = config.model_package_path
|
58
|
+
else
|
59
|
+
raise "Unsupported model type for converter definition: #{obj.inspect}"
|
60
|
+
end
|
61
|
+
TypeRef.new(pkg_name, pkg_path).tap do |t|
|
62
|
+
t.package_base_path = pkg_base_path
|
63
|
+
t.slice_with_ptr = slice_with_ptr
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def load_mappings(hash, conv_class)
|
68
|
+
hash.map do |(name, props)|
|
69
|
+
props ||= {}
|
70
|
+
props = {'arg' => props} if props.is_a?(String)
|
71
|
+
args = props['args'] || [props['arg'] || name]
|
72
|
+
func, requires_context, returns_error = *conv_class.load_func(props)
|
73
|
+
if func.nil? && (args.length > 1)
|
74
|
+
raise "Invalid argument length: #{args.length} for #{name}: #{args.inspect}"
|
75
|
+
end
|
76
|
+
Mapping.new(name, args, func, requires_context, returns_error).tap do |m|
|
77
|
+
m.allow_zero = props['allow_zero']
|
78
|
+
m.resolve_package_path(config)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "goon_model_gen"
|
2
|
+
|
3
|
+
module GoonModelGen
|
4
|
+
module Converter
|
5
|
+
class Mapping
|
6
|
+
attr_reader :name, :args, :func, :requires_context, :returns_error
|
7
|
+
attr_accessor :package_base_path, :package_name
|
8
|
+
attr_accessor :allow_zero # for int or uint only
|
9
|
+
def initialize(name, args, func, requires_context, returns_error)
|
10
|
+
@name, @args, @func, @requires_context, @returns_error = name, args, func, requires_context, returns_error
|
11
|
+
end
|
12
|
+
|
13
|
+
def resolve_package_path(config)
|
14
|
+
if func.present? && func.include?('.')
|
15
|
+
self.package_base_path = requires_context ? config.store_package_path : config.model_package_path
|
16
|
+
self.package_name = func.split('.', 2).first
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "goon_model_gen"
|
2
|
+
|
3
|
+
require "goon_model_gen/converter/abstract_conv"
|
4
|
+
|
5
|
+
module GoonModelGen
|
6
|
+
module Converter
|
7
|
+
class PayloadConv < AbstractConv
|
8
|
+
class << self
|
9
|
+
# @return [String, boolean, boolean] func, requires_context, returns_error
|
10
|
+
def load_func(props)
|
11
|
+
if f = props['filter']
|
12
|
+
return f, false, false
|
13
|
+
elsif f = props['reader']
|
14
|
+
return f, false, true
|
15
|
+
elsif f = props['loader']
|
16
|
+
return f, true, true
|
17
|
+
else
|
18
|
+
return nil, nil, nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "goon_model_gen"
|
2
|
+
|
3
|
+
require "goon_model_gen/converter/abstract_conv"
|
4
|
+
|
5
|
+
module GoonModelGen
|
6
|
+
module Converter
|
7
|
+
class ResultConv < AbstractConv
|
8
|
+
|
9
|
+
class << self
|
10
|
+
# @return [String, boolean, boolean] func, requires_context, returns_error
|
11
|
+
def load_func(props)
|
12
|
+
if f = props['filter']
|
13
|
+
return f, false, false
|
14
|
+
elsif f = props['writer']
|
15
|
+
return f, false, true
|
16
|
+
else
|
17
|
+
return nil, nil, nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "goon_model_gen"
|
2
|
+
|
3
|
+
module GoonModelGen
|
4
|
+
module Converter
|
5
|
+
class TypeRef
|
6
|
+
attr_reader :name, :package_path
|
7
|
+
attr_accessor :package_base_path
|
8
|
+
attr_accessor :slice_with_ptr
|
9
|
+
def initialize(name, package_path)
|
10
|
+
@name, @package_path = name, package_path
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -9,7 +9,8 @@ module GoonModelGen
|
|
9
9
|
TYPE_NAMES =
|
10
10
|
%w[bool byte complex128 complex64
|
11
11
|
error float32 float64 int int16 int32 int64 int8
|
12
|
-
rune string uint uint16 uint32 uint64 uint8 uintptr
|
12
|
+
rune string uint uint16 uint32 uint64 uint8 uintptr
|
13
|
+
interface] # interface is not a type but is added to ease to treat any type
|
13
14
|
|
14
15
|
class << self
|
15
16
|
def package
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "goon_model_gen"
|
2
|
+
|
3
|
+
require "goon_model_gen/golang/type"
|
4
|
+
|
5
|
+
module GoonModelGen
|
6
|
+
module Golang
|
7
|
+
class CombinationType < Type
|
8
|
+
class ItemType
|
9
|
+
attr_reader :name, :package_path, :package_base_path
|
10
|
+
attr_reader :type
|
11
|
+
def initialize(name, package_path, package_base_path = nil)
|
12
|
+
@name, @package_path, @package_base_path = name, package_path, package_base_path
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_hash
|
16
|
+
{name: name, package_path: package_path, package_base_path: package_base_path}
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param pkgs [Packages]
|
20
|
+
def resolve(pkgs)
|
21
|
+
@type = pkgs.type_by(**to_hash) || raise("Type not found by #{to_hash.inspect}")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_reader :map
|
26
|
+
|
27
|
+
# @param name [String]
|
28
|
+
def initialize(name)
|
29
|
+
super(name)
|
30
|
+
@map = {}
|
31
|
+
end
|
32
|
+
|
33
|
+
def add(key, name, package_path, package_base_path = nil)
|
34
|
+
map[key] = ItemType.new(name, package_path, package_base_path)
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param pkgs [Packages]
|
38
|
+
def resolve(pkgs)
|
39
|
+
map.each do |_, item|
|
40
|
+
item.resolve(pkgs)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -19,7 +19,7 @@ module GoonModelGen
|
|
19
19
|
|
20
20
|
# @param pkgs [Packages]
|
21
21
|
def resolve(pkgs)
|
22
|
-
@base_type = pkgs.type_for(base_type_name) || raise("#{base_type_name.inspect} not found")
|
22
|
+
@base_type = pkgs.type_for(base_type_name) || raise("#{base_type_name.inspect} not found for #{name}")
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -1,5 +1,11 @@
|
|
1
1
|
require "goon_model_gen"
|
2
2
|
|
3
|
+
require "goon_model_gen/golang/type"
|
4
|
+
require "goon_model_gen/golang/struct"
|
5
|
+
require "goon_model_gen/golang/named_slice"
|
6
|
+
require "goon_model_gen/golang/builtin"
|
7
|
+
require "goon_model_gen/golang/modifier"
|
8
|
+
|
3
9
|
module GoonModelGen
|
4
10
|
module Golang
|
5
11
|
class Field
|
@@ -37,6 +43,51 @@ module GoonModelGen
|
|
37
43
|
(type.package.path == pkg.path) ? type.name : type.qualified_name
|
38
44
|
"#{ name } #{ type_exp } `#{ tags_string }`"
|
39
45
|
end
|
46
|
+
|
47
|
+
def ptr?
|
48
|
+
case type
|
49
|
+
when Modifier then (type.prefix == "*")
|
50
|
+
when Type then false
|
51
|
+
else raise "Unsupported type class #{type.inspect}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def slice?
|
56
|
+
case type
|
57
|
+
when Modifier then (type.prefix == "[]")
|
58
|
+
when NamedSlice then true
|
59
|
+
when Type then false
|
60
|
+
else raise "Unsupported type class #{type.inspect}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def struct?
|
65
|
+
case type
|
66
|
+
when Modifier then false
|
67
|
+
when Struct then true
|
68
|
+
when Type then false
|
69
|
+
else raise "Unsupported type class #{type.inspect}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def value_ptr?
|
74
|
+
case type
|
75
|
+
when Modifier then
|
76
|
+
return false unless type.prefix == '*'
|
77
|
+
case type.target
|
78
|
+
when Builtin then type.target.name != 'interface'
|
79
|
+
else false
|
80
|
+
end
|
81
|
+
when Type then false
|
82
|
+
else raise "Unsupported type class #{type.inspect}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# @param pkg2alias [Hash<String,String>]
|
87
|
+
# @return [string]
|
88
|
+
def short_desc(pkg2alias = nil)
|
89
|
+
"#{name}: #{type.qualified_name(pkg2alias)}"
|
90
|
+
end
|
40
91
|
end
|
41
92
|
end
|
42
93
|
end
|
@@ -5,14 +5,13 @@ require "goon_model_gen/golang/sentence"
|
|
5
5
|
module GoonModelGen
|
6
6
|
module Golang
|
7
7
|
class File
|
8
|
-
attr_reader :
|
8
|
+
attr_reader :name
|
9
9
|
attr_reader :sentences
|
10
|
+
attr_accessor :package
|
10
11
|
attr_accessor :custom_suffix # false/true
|
11
12
|
|
12
|
-
# @param package [Package]
|
13
13
|
# @param name [string]
|
14
|
-
def initialize(
|
15
|
-
@package = package
|
14
|
+
def initialize(name)
|
16
15
|
@name = name
|
17
16
|
@sentences = []
|
18
17
|
end
|
@@ -27,8 +27,10 @@ module GoonModelGen
|
|
27
27
|
prefix + target.name
|
28
28
|
end
|
29
29
|
|
30
|
-
|
31
|
-
|
30
|
+
# @param pkg2alias [Hash<String,String>]
|
31
|
+
# @return [string]
|
32
|
+
def qualified_name(pkg2alias = nil)
|
33
|
+
prefix + target.qualified_name(pkg2alias)
|
32
34
|
end
|
33
35
|
|
34
36
|
# @param pkgs [Packages]
|
@@ -6,18 +6,28 @@ module GoonModelGen
|
|
6
6
|
module Golang
|
7
7
|
class NamedSlice < Type
|
8
8
|
attr_reader :base_type_name
|
9
|
+
attr_reader :base_type_package_path
|
9
10
|
attr_reader :base_type
|
10
11
|
|
11
12
|
# @param name [String]
|
12
13
|
# @param base_type_name [String]
|
13
|
-
|
14
|
+
# @param base_type_package_path [String]
|
15
|
+
def initialize(name, base_type_name, base_type_package_path = nil)
|
14
16
|
super(name)
|
15
17
|
@base_type_name = base_type_name
|
18
|
+
@base_type_package_path = base_type_package_path
|
16
19
|
end
|
17
20
|
|
18
21
|
# @param pkgs [Packages]
|
19
22
|
def resolve(pkgs)
|
20
|
-
@base_type =
|
23
|
+
@base_type =
|
24
|
+
base_type_package_path.present? ?
|
25
|
+
pkgs.type_for(base_type_name, base_type_package_path) :
|
26
|
+
pkgs.type_for(base_type_name) || raise("#{base_type_name.inspect} not found")
|
27
|
+
end
|
28
|
+
|
29
|
+
def ptr_slice?
|
30
|
+
base_type.is_a?(GoonModelGen::Golang::Modifier) && (base_type.prefix == '*')
|
21
31
|
end
|
22
32
|
end
|
23
33
|
end
|
@@ -3,6 +3,7 @@ require "goon_model_gen"
|
|
3
3
|
require "goon_model_gen/golang/struct"
|
4
4
|
require "goon_model_gen/golang/enum"
|
5
5
|
require "goon_model_gen/golang/named_slice"
|
6
|
+
require "goon_model_gen/golang/combination_type"
|
6
7
|
require "goon_model_gen/golang/file"
|
7
8
|
|
8
9
|
module GoonModelGen
|
@@ -20,13 +21,25 @@ module GoonModelGen
|
|
20
21
|
end
|
21
22
|
|
22
23
|
def basename
|
23
|
-
@basename ||= path ? ::File.basename(path, '.*') : nil
|
24
|
+
@basename ||= (path ? ::File.basename(path, '.*') : nil)
|
24
25
|
end
|
25
26
|
|
26
27
|
def name
|
27
28
|
@name ||= basename ? basename.gsub(/[\-\_]/, '').downcase : nil
|
28
29
|
end
|
29
30
|
|
31
|
+
def merge!(other)
|
32
|
+
other.types.each{|t| add(t) unless types.any?{|oldt| oldt.name == t.name } }
|
33
|
+
other.files.each{|f| add_file(f) unless files.any?{|oldf| oldf.name == f.name } }
|
34
|
+
end
|
35
|
+
|
36
|
+
# @param file [File]
|
37
|
+
def add_file(file)
|
38
|
+
files.push(file)
|
39
|
+
file.package = self
|
40
|
+
end
|
41
|
+
|
42
|
+
# @param type [Type]
|
30
43
|
def add(type)
|
31
44
|
types.push(type)
|
32
45
|
type.package = self
|
@@ -45,10 +58,17 @@ module GoonModelGen
|
|
45
58
|
end
|
46
59
|
|
47
60
|
# @param name [string]
|
61
|
+
# @param base_type_package_path [String]
|
48
62
|
# @param base_type_name [String]
|
49
63
|
# @return [Slice]
|
50
|
-
def new_named_slice(name, base_type_name)
|
51
|
-
NamedSlice.new(name,
|
64
|
+
def new_named_slice(name, base_type_name, base_type_package_path = nil)
|
65
|
+
NamedSlice.new(name, base_type_name, base_type_package_path).tap{|s| add(s) }
|
66
|
+
end
|
67
|
+
|
68
|
+
# @param name [string]
|
69
|
+
# @return [CombinationType]
|
70
|
+
def new_combination_type(name)
|
71
|
+
CombinationType.new(name).tap{|s| add(s) }
|
52
72
|
end
|
53
73
|
|
54
74
|
# @param name [string]
|
@@ -60,8 +80,8 @@ module GoonModelGen
|
|
60
80
|
# @param name [string]
|
61
81
|
# @return [File]
|
62
82
|
def new_file(name)
|
63
|
-
File.new(
|
64
|
-
|
83
|
+
File.new(name).tap do |f|
|
84
|
+
add_file(f)
|
65
85
|
end
|
66
86
|
end
|
67
87
|
|
@@ -9,6 +9,17 @@ module GoonModelGen
|
|
9
9
|
module Golang
|
10
10
|
class Packages < Array
|
11
11
|
|
12
|
+
class << self
|
13
|
+
def wrap(obj)
|
14
|
+
case obj
|
15
|
+
when Packages then obj
|
16
|
+
when Package then Packages.new.add(obj)
|
17
|
+
when Array then Packages.new.add(*obj)
|
18
|
+
else raise "Unsupported obj for #{self.name}.wrap #{obj.inspect}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
12
23
|
def name_to_type_map
|
13
24
|
each_with_object({}) do |pkg, d|
|
14
25
|
d.update(pkg.name_to_type_map)
|
@@ -20,8 +31,12 @@ module GoonModelGen
|
|
20
31
|
end
|
21
32
|
|
22
33
|
def add(*packages)
|
23
|
-
packages.each do |i|
|
24
|
-
|
34
|
+
packages.flatten.each do |i|
|
35
|
+
if pkg = find_by_path(i.path)
|
36
|
+
pkg.merge!(i)
|
37
|
+
else
|
38
|
+
self << i
|
39
|
+
end
|
25
40
|
end
|
26
41
|
self
|
27
42
|
end
|
@@ -30,8 +45,20 @@ module GoonModelGen
|
|
30
45
|
Package.new(path).tap{|pkg| add(pkg)}
|
31
46
|
end
|
32
47
|
|
33
|
-
def detect_by(
|
34
|
-
detect{|pkg| pkg.
|
48
|
+
def detect_by(name)
|
49
|
+
detect{|pkg| pkg.name == name}
|
50
|
+
end
|
51
|
+
|
52
|
+
def find_by_path(path)
|
53
|
+
detect{|pkg| pkg.path == path}
|
54
|
+
end
|
55
|
+
|
56
|
+
def find_or_new(path)
|
57
|
+
find_by_path(path) || new_package(path)
|
58
|
+
end
|
59
|
+
|
60
|
+
def select_by(name)
|
61
|
+
select{|pkg| pkg.name == name}
|
35
62
|
end
|
36
63
|
|
37
64
|
def resolve_type_names(extra_packages = [])
|
@@ -43,25 +70,50 @@ module GoonModelGen
|
|
43
70
|
end
|
44
71
|
|
45
72
|
# @param type_name [string]
|
73
|
+
# @param package_path [string]
|
46
74
|
# @param [Type]
|
47
|
-
def lookup(type_name)
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
75
|
+
def lookup(type_name, package_path = nil)
|
76
|
+
lookup_by(name: type_name, package_path: package_path)
|
77
|
+
end
|
78
|
+
|
79
|
+
# @param name [String]
|
80
|
+
# @param package_path [String]
|
81
|
+
# @param package_base_path [String]
|
82
|
+
# @param [Type]
|
83
|
+
def lookup_by(name: nil, package_path: nil, package_base_path: nil)
|
84
|
+
pkg_name, type_name = name.include?('.') ? name.split('.', 2) : [nil, name]
|
85
|
+
if package_path.present?
|
86
|
+
pkg = find_by_path(package_path) || raise("Package not found #{package_path.inspect} for type #{name.inspect}")
|
87
|
+
return pkg.lookup(type_name)
|
88
|
+
end
|
89
|
+
|
90
|
+
pkgs =
|
91
|
+
package_base_path.blank? ? self :
|
92
|
+
self.class.wrap(select{|pkg| pkg.path ? pkg.path.include?(package_base_path) : false})
|
93
|
+
if pkg_name.present?
|
94
|
+
pkgs = pkgs.select_by(pkg_name)
|
95
|
+
raise("Package not found #{pkg_name.inspect} for type #{name.inspect}") if pkgs.empty?
|
96
|
+
return self.class.wrap(pkgs).lookup(type_name)
|
58
97
|
end
|
98
|
+
|
99
|
+
each do |pkg|
|
100
|
+
t = pkg.lookup(type_name)
|
101
|
+
return t if t
|
102
|
+
end
|
103
|
+
return nil
|
59
104
|
end
|
60
105
|
|
61
|
-
def type_for(expression)
|
106
|
+
def type_for(expression, package_path = nil)
|
62
107
|
return nil if expression.blank?
|
63
108
|
Modifier.parse(expression) do |name|
|
64
|
-
lookup(name)
|
109
|
+
lookup(name, package_path)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def type_by(name: nil, package_path: nil, package_base_path: nil)
|
114
|
+
return nil if name.blank?
|
115
|
+
Modifier.parse(name) do |type_name|
|
116
|
+
lookup_by(name: type_name, package_path: package_path, package_base_path: package_base_path)
|
65
117
|
end
|
66
118
|
end
|
67
119
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require "goon_model_gen"
|
2
|
+
|
3
|
+
require "erb"
|
4
|
+
require "yaml"
|
5
|
+
|
6
|
+
require "goon_model_gen/golang/packages"
|
7
|
+
require "goon_model_gen/golang/datastore_supported"
|
8
|
+
|
9
|
+
require "active_support/core_ext/string"
|
10
|
+
|
11
|
+
module GoonModelGen
|
12
|
+
module Golang
|
13
|
+
class StructsLoader
|
14
|
+
|
15
|
+
# @param path [String]
|
16
|
+
# @return [Hash<String,Packages>]
|
17
|
+
def process(path)
|
18
|
+
erb = ERB.new(::File.read(path), nil, "-")
|
19
|
+
erb.filename = path
|
20
|
+
txt = erb.result
|
21
|
+
raw = YAML.load(txt)
|
22
|
+
|
23
|
+
r = raw.each_with_object({}) do |(key, types), d|
|
24
|
+
d[key] = build_packages(types)
|
25
|
+
end
|
26
|
+
|
27
|
+
whole_packages = Golang::DatastoreSupported.packages.dup
|
28
|
+
r.values.each do |pkgs|
|
29
|
+
whole_packages.add(*pkgs)
|
30
|
+
end
|
31
|
+
|
32
|
+
r.values.each do |pkgs|
|
33
|
+
pkgs.resolve_type_names(whole_packages)
|
34
|
+
end
|
35
|
+
return r
|
36
|
+
end
|
37
|
+
|
38
|
+
def build_packages(types)
|
39
|
+
Packages.new.tap do |pkgs|
|
40
|
+
types.each do |type_hash|
|
41
|
+
next if type_hash['PkgPath'].blank? || type_hash['Name'].blank?
|
42
|
+
pkg = pkgs.find_or_new(type_hash['PkgPath'])
|
43
|
+
if type_hash['Fields']
|
44
|
+
pkg.new_struct(type_hash['Name']).tap do |s|
|
45
|
+
type_hash['Fields'].each do |f|
|
46
|
+
t = f['Type']
|
47
|
+
tags = (f['Tag'] || {}).each_with_object({}){|(k,v), d| d[k] = v.split(',')}
|
48
|
+
s.new_field(f['Name'], t['Representation'], tags)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
elsif type_hash['Kind'] == 'slice'
|
52
|
+
base_type_hash = base_type_hash_from(type_hash['Elem'])
|
53
|
+
pkg.new_named_slice(type_hash['Name'], base_type_hash['Name'], base_type_hash['PkgPath'])
|
54
|
+
else
|
55
|
+
pkg.new_enum(type_hash['Name'], type_hash['Kind'], {})
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def base_type_hash_from(type_hash)
|
62
|
+
type_hash['Elem'].nil? ? type_hash : base_type_name_from(type_hash['Elem'])
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -16,10 +16,12 @@ module GoonModelGen
|
|
16
16
|
raise NotImplementedError, "#{self.type.name} doesn't implement resolve method"
|
17
17
|
end
|
18
18
|
|
19
|
+
# @param pkg2alias [Hash<String,String>]
|
19
20
|
# @return [string]
|
20
|
-
def qualified_name
|
21
|
+
def qualified_name(pkg2alias = nil)
|
21
22
|
if package && package.name
|
22
|
-
|
23
|
+
pkg_name = (pkg2alias && package.path ? pkg2alias[package.path] : nil) || package.name
|
24
|
+
"#{pkg_name}.#{name}"
|
23
25
|
else
|
24
26
|
name
|
25
27
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<%-
|
2
|
+
model = type.map[:model].type
|
3
|
+
gen_type = type.map[:gen_type].type
|
4
|
+
|
5
|
+
import model.package
|
6
|
+
import :gen, gen_type.package
|
7
|
+
|
8
|
+
mappings = type.memo['mappings'] || []
|
9
|
+
requires_context = mappings.any?(&:requires_context)
|
10
|
+
import 'context' if requires_context
|
11
|
+
-%>
|
@@ -0,0 +1,45 @@
|
|
1
|
+
<%-
|
2
|
+
import converter_package
|
3
|
+
|
4
|
+
model = type.map[:model].type
|
5
|
+
gen_type = type.map[:gen_type].type
|
6
|
+
mappings = type.memo['mappings'] || []
|
7
|
+
requires_context = mappings.any?(&:requires_context)
|
8
|
+
arg_def_prefix = requires_context ? 'ctx context.Context, ' : nil
|
9
|
+
arg_prefix = requires_context ? 'ctx, ' : nil
|
10
|
+
|
11
|
+
model_slice = model.package.types.detect do |t|
|
12
|
+
t.is_a?(GoonModelGen::Golang::NamedSlice) &&
|
13
|
+
(
|
14
|
+
(t.base_type == model) ||
|
15
|
+
(t.ptr_slice? && (t.base_type.target == model))
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
if model_slice
|
20
|
+
element_is_ptr = model_slice.ptr_slice?
|
21
|
+
plural_model_type_name = model_slice.qualified_name
|
22
|
+
else
|
23
|
+
element_is_ptr =
|
24
|
+
!type.memo['model_slice_with_ptr'].nil? ? type.memo['model_slice_with_ptr'] :
|
25
|
+
model.fields.any?{|f| !f.tags['goon'].nil? }
|
26
|
+
plural_model_type_name = (element_is_ptr ? '[]*' : '[]') + model.qualified_name
|
27
|
+
end
|
28
|
+
-%>
|
29
|
+
|
30
|
+
func <%= gen_type.name %>SliceToModelSlice(<%= arg_def_prefix %>payloads *[]*<%= gen_type.qualified_name(dependencies) %>) (*<%= plural_model_type_name %>, error) {
|
31
|
+
if payloads == nil {
|
32
|
+
return nil, <%= converter_package.name %>.NoPayloadGiven
|
33
|
+
}
|
34
|
+
|
35
|
+
s := <%= plural_model_type_name %>{}
|
36
|
+
for _, payload := range *payloads {
|
37
|
+
m, err := <%= gen_type.name %>ToModel(<%= arg_prefix %>payload)
|
38
|
+
if err != nil {
|
39
|
+
return nil, err
|
40
|
+
}
|
41
|
+
s = append(s, <%= element_is_ptr ? '' : '*' %>m)
|
42
|
+
}
|
43
|
+
|
44
|
+
return &s, nil
|
45
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<%-
|
2
|
+
import converter_package
|
3
|
+
|
4
|
+
model = type.map[:model].type
|
5
|
+
gen_type = type.map[:gen_type].type
|
6
|
+
mappings = type.memo['mappings'] || []
|
7
|
+
requires_context = mappings.any?(&:requires_context)
|
8
|
+
arg_def_prefix = requires_context ? 'ctx context.Context, ' : nil
|
9
|
+
arg_prefix = requires_context ? 'ctx, ' : nil
|
10
|
+
-%>
|
11
|
+
|
12
|
+
func <%= gen_type.name %>ToModel(<%= arg_def_prefix %>payload *<%= gen_type.qualified_name(dependencies) %>) (*<%= model.qualified_name %>, error) {
|
13
|
+
if payload == nil {
|
14
|
+
return nil, <%= converter_package.name %>.NoPayloadGiven
|
15
|
+
}
|
16
|
+
var m <%= model.qualified_name %>
|
17
|
+
if err := <%= gen_type.name %>AssignModel(<%= arg_prefix %>payload, &m); err != nil {
|
18
|
+
return nil, err
|
19
|
+
}
|
20
|
+
return &m, nil
|
21
|
+
}
|
@@ -0,0 +1,90 @@
|
|
1
|
+
<%-
|
2
|
+
model = type.map[:model].type
|
3
|
+
gen_type = type.map[:gen_type].type
|
4
|
+
mappings = type.memo['mappings'] || []
|
5
|
+
requires_context = mappings.any?(&:requires_context)
|
6
|
+
arg_def_prefix = requires_context ? 'ctx context.Context, ' : nil
|
7
|
+
arg_prefix = requires_context ? 'ctx, ' : nil
|
8
|
+
-%>
|
9
|
+
|
10
|
+
func <%= gen_type.name %>AssignModel(<%= arg_def_prefix %>payload *<%= gen_type.qualified_name(dependencies) %>, m *<%= model.qualified_name %>) error {
|
11
|
+
if payload == nil {
|
12
|
+
return converters.NoPayloadGiven
|
13
|
+
}
|
14
|
+
if m == nil {
|
15
|
+
return converters.NoModelGiven
|
16
|
+
}
|
17
|
+
|
18
|
+
<%-
|
19
|
+
mappings.each do |mapping|
|
20
|
+
import GoonModelGen::Golang::Packages.wrap(packages).detect_by(mapping.package_name) if mapping.package_name.present?
|
21
|
+
|
22
|
+
mfield = model.fields.detect{|f| f.name == mapping.name} || raise("Field not found #{mapping.name} of #{model.package.path}.#{model.name}")
|
23
|
+
argFields = mapping.args.map do |arg|
|
24
|
+
gen_type.fields.detect{|f| f.name == arg} ||
|
25
|
+
raise("Field not found #{arg.inspect} of #{gen_type.package.path}.#{gen_type.name}")
|
26
|
+
end
|
27
|
+
-%>
|
28
|
+
// <%= mfield.short_desc(dependencies) %> <== <%= argFields.map{|f| f.short_desc(dependencies) }.join(', ') %>
|
29
|
+
<%- if mapping.args.length == 1 -%>
|
30
|
+
<%-
|
31
|
+
pfield = argFields.first
|
32
|
+
|
33
|
+
assignable_condition = nil
|
34
|
+
if pfield.ptr?
|
35
|
+
assignable_condition = "payload.#{ pfield.name } != nil"
|
36
|
+
if !mapping.allow_zero && pfield.value_ptr? && pfield.type.target.name =~ /\Aint\z|\Aint8\z|\Aint16\z|\Aint32\z|\Aint64\z|\Auint\z|\Auint8\z|\Auint16\z|\Auint32\z|\Auint64\z/
|
37
|
+
assignable_condition << " && *payload.#{ pfield.name } != 0"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
if mapping.func.nil? || !mapping.returns_error
|
41
|
+
arg = '%spayload.%s' % [pfield.ptr? ? '*' : '', pfield.name]
|
42
|
+
right_side = mapping.func.blank? ? arg :
|
43
|
+
'%s(%s%s)' % [mapping.func, mapping.requires_context ? 'ctx, ' : '', arg]
|
44
|
+
-%>
|
45
|
+
<%- if assignable_condition -%>
|
46
|
+
if <%= assignable_condition %> {
|
47
|
+
m.<%= mfield.name %> = <%= right_side %>
|
48
|
+
}
|
49
|
+
<%- else -%>
|
50
|
+
m.<%= mfield.name %> = <%= right_side %>
|
51
|
+
<%- end -%>
|
52
|
+
<%-
|
53
|
+
else
|
54
|
+
arg = '%spayload.%s' % [pfield.ptr? ? '*' : pfield.slice? ? '&' :'', pfield.name]
|
55
|
+
right_side = '%s(%s%s)' % [mapping.func, mapping.requires_context ? 'ctx, ' : '', arg]
|
56
|
+
-%>
|
57
|
+
<%- if assignable_condition -%>
|
58
|
+
if <%= assignable_condition %> {
|
59
|
+
<%- end -%>
|
60
|
+
if v, err := <%= right_side %>; err != nil {
|
61
|
+
return err
|
62
|
+
} else {
|
63
|
+
m.<%= mfield.name %> = <%= (pfield.slice? || mapping.requires_context) ? '*' : '' %>v
|
64
|
+
}
|
65
|
+
<%- if assignable_condition -%>
|
66
|
+
}
|
67
|
+
<%- end -%>
|
68
|
+
<%- end -%>
|
69
|
+
|
70
|
+
<%- else -%>
|
71
|
+
<%- arg_str = argFields.map{|f| "payload.#{f.name}"}.join(", ") %>
|
72
|
+
<%- if !mapping.returns_error # => requries_context is false -%>
|
73
|
+
m.<%= mfield.name %> = <%= mapping.func %>(<%= arg_str %>)
|
74
|
+
<%- else
|
75
|
+
arg_str = (mapping.requries_context ? 'ctx, ' : '') + arg_str
|
76
|
+
-%>
|
77
|
+
if v, err := <%= mapping.func %>(<%= arg_str %>); err != nil {
|
78
|
+
return err
|
79
|
+
} else {
|
80
|
+
m.<%= mfield.name %> = v
|
81
|
+
}
|
82
|
+
<%- end -%>
|
83
|
+
|
84
|
+
<%- end -%>
|
85
|
+
|
86
|
+
<%-
|
87
|
+
end
|
88
|
+
-%>
|
89
|
+
return nil
|
90
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<%-
|
2
|
+
model = type.map[:model].type
|
3
|
+
gen_type = type.map[:gen_type].type
|
4
|
+
mappings = type.memo['mappings'] || []
|
5
|
+
|
6
|
+
import model.package
|
7
|
+
import :gen, gen_type.package
|
8
|
+
|
9
|
+
if mappings.any?{|m| m.args.length > 1}
|
10
|
+
raise "Multiple arguments for result type mapping is not supported now"
|
11
|
+
end
|
12
|
+
if mappings.any?(&:returns_error)
|
13
|
+
raise "returns_error (by writer) for result type mapping is not supported now"
|
14
|
+
end
|
15
|
+
if mappings.any?(&:requires_context)
|
16
|
+
raise "requires_context (by saver) for result type mapping is not supported now"
|
17
|
+
end
|
18
|
+
-%>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<%-
|
2
|
+
model = type.map[:model].type
|
3
|
+
gen_type = type.map[:gen_type].type
|
4
|
+
|
5
|
+
model_slice = model.package.types.detect do |t|
|
6
|
+
t.is_a?(GoonModelGen::Golang::NamedSlice) &&
|
7
|
+
(
|
8
|
+
(t.base_type == model) ||
|
9
|
+
(t.ptr_slice? && (t.base_type.target == model))
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
if model_slice
|
14
|
+
element_is_ptr = model_slice.ptr_slice?
|
15
|
+
plural_model_type_name = model_slice.qualified_name
|
16
|
+
else
|
17
|
+
element_is_ptr =
|
18
|
+
!type.memo['model_slice_with_ptr'].nil? ? type.memo['model_slice_with_ptr'] :
|
19
|
+
model.fields.any?{|f| !f.tags['goon'].nil? }
|
20
|
+
plural_model_type_name = (element_is_ptr ? '[]*' : '[]') + model.qualified_name
|
21
|
+
end
|
22
|
+
-%>
|
23
|
+
|
24
|
+
func <%= model.name %>SliceToResultSlice(s *<%= plural_model_type_name %>) *[]*<%= gen_type.qualified_name(dependencies) %> {
|
25
|
+
if s == nil {
|
26
|
+
return nil
|
27
|
+
}
|
28
|
+
r := []*<%= gen_type.qualified_name(dependencies) %>{}
|
29
|
+
for _, m := range *s {
|
30
|
+
r = append(r, <%= model.name %>ToResult(<%= element_is_ptr ? '' : '&' %>m))
|
31
|
+
}
|
32
|
+
return &r
|
33
|
+
}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
<%-
|
2
|
+
model = type.map[:model].type
|
3
|
+
gen_type = type.map[:gen_type].type
|
4
|
+
mappings = type.memo['mappings'] || []
|
5
|
+
-%>
|
6
|
+
|
7
|
+
|
8
|
+
func <%= model.name %>ToResult(m *<%= model.qualified_name %>) *<%= gen_type.qualified_name(dependencies) %> {
|
9
|
+
if m == nil {
|
10
|
+
return nil
|
11
|
+
}
|
12
|
+
r := &<%= gen_type.qualified_name(dependencies) %>{}
|
13
|
+
|
14
|
+
<%-
|
15
|
+
mappings.each do |mapping|
|
16
|
+
import GoonModelGen::Golang::Packages.wrap(packages).detect_by(mapping.package_name) if mapping.package_name.present?
|
17
|
+
|
18
|
+
rfield = gen_type.fields.detect{|f| f.name == mapping.name} || raise("Field not found #{mapping.name} of #{gen_type.package.path}.#{gen_type.name}")
|
19
|
+
arg_fields = mapping.args.map do |arg|
|
20
|
+
model.fields.detect{|f| f.name == arg} ||
|
21
|
+
raise("Field not found #{arg.inspect} of #{model.package.path}.#{model.name}")
|
22
|
+
end
|
23
|
+
-%>
|
24
|
+
// <%= rfield.short_desc(dependencies) %> <== <%= arg_fields.map{|f| f.short_desc(dependencies) }.join(', ') %>
|
25
|
+
<%-
|
26
|
+
mfield = arg_fields.first
|
27
|
+
arg = "m.#{mfield.name}"
|
28
|
+
if mfield.struct? || mfield.slice?
|
29
|
+
arg = "&#{arg}"
|
30
|
+
raise "Struct field or Slice field requires func for mapping" if mapping.func.blank?
|
31
|
+
end
|
32
|
+
right_side_main = mapping.func ? "#{mapping.func}(#{arg})" : arg
|
33
|
+
right_side = (rfield.slice? ? '*' : '') + right_side_main
|
34
|
+
-%>
|
35
|
+
<%- if rfield.value_ptr? -%>
|
36
|
+
{
|
37
|
+
v := <%= right_side_main %>
|
38
|
+
r.<%= rfield.name %> = &v
|
39
|
+
}
|
40
|
+
|
41
|
+
<%- else -%>
|
42
|
+
r.<%= rfield.name %> = <%= right_side %>
|
43
|
+
|
44
|
+
<%- end -%>
|
45
|
+
<%-
|
46
|
+
end
|
47
|
+
-%>
|
48
|
+
|
49
|
+
return r
|
50
|
+
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: goon_model_gen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- akm
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-05-
|
11
|
+
date: 2019-05-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -144,14 +144,23 @@ files:
|
|
144
144
|
- goon_model_gen.gemspec
|
145
145
|
- lib/goon_model_gen.rb
|
146
146
|
- lib/goon_model_gen/builder/abstract_builder.rb
|
147
|
+
- lib/goon_model_gen/builder/converter_builder.rb
|
147
148
|
- lib/goon_model_gen/builder/model_builder.rb
|
148
149
|
- lib/goon_model_gen/builder/store_builder.rb
|
149
150
|
- lib/goon_model_gen/builder/validation_builder.rb
|
150
151
|
- lib/goon_model_gen/cli.rb
|
151
152
|
- lib/goon_model_gen/config.rb
|
153
|
+
- lib/goon_model_gen/converter/abstract_conv.rb
|
154
|
+
- lib/goon_model_gen/converter/conv_file.rb
|
155
|
+
- lib/goon_model_gen/converter/loader.rb
|
156
|
+
- lib/goon_model_gen/converter/mapping.rb
|
157
|
+
- lib/goon_model_gen/converter/payload_conv.rb
|
158
|
+
- lib/goon_model_gen/converter/result_conv.rb
|
159
|
+
- lib/goon_model_gen/converter/type_ref.rb
|
152
160
|
- lib/goon_model_gen/generator.rb
|
153
161
|
- lib/goon_model_gen/golang.rb
|
154
162
|
- lib/goon_model_gen/golang/builtin.rb
|
163
|
+
- lib/goon_model_gen/golang/combination_type.rb
|
155
164
|
- lib/goon_model_gen/golang/datastore_supported.rb
|
156
165
|
- lib/goon_model_gen/golang/enum.rb
|
157
166
|
- lib/goon_model_gen/golang/field.rb
|
@@ -163,6 +172,7 @@ files:
|
|
163
172
|
- lib/goon_model_gen/golang/predeclared_type.rb
|
164
173
|
- lib/goon_model_gen/golang/sentence.rb
|
165
174
|
- lib/goon_model_gen/golang/struct.rb
|
175
|
+
- lib/goon_model_gen/golang/structs_loader.rb
|
166
176
|
- lib/goon_model_gen/golang/type.rb
|
167
177
|
- lib/goon_model_gen/source/context.rb
|
168
178
|
- lib/goon_model_gen/source/contextual.rb
|
@@ -173,6 +183,13 @@ files:
|
|
173
183
|
- lib/goon_model_gen/source/named_slice.rb
|
174
184
|
- lib/goon_model_gen/source/struct.rb
|
175
185
|
- lib/goon_model_gen/source/type.rb
|
186
|
+
- lib/goon_model_gen/templates/converter/payload/01_base_imports.go.erb
|
187
|
+
- lib/goon_model_gen/templates/converter/payload/02_SliceToModelSlice.go.erb
|
188
|
+
- lib/goon_model_gen/templates/converter/payload/03_ToModel.go.erb
|
189
|
+
- lib/goon_model_gen/templates/converter/payload/04_AssignModel.go.erb
|
190
|
+
- lib/goon_model_gen/templates/converter/result/01_base_imports.go.erb
|
191
|
+
- lib/goon_model_gen/templates/converter/result/02_SliceToResultSlice.go.erb
|
192
|
+
- lib/goon_model_gen/templates/converter/result/03_ToResult.go.erb
|
176
193
|
- lib/goon_model_gen/templates/dsl.rb
|
177
194
|
- lib/goon_model_gen/templates/model/enum/01_base.go.erb
|
178
195
|
- lib/goon_model_gen/templates/model/enum/02_All.go.erb
|