goon_model_gen 0.1.3 → 0.2.0
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/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
|