-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcodegen.rb
105 lines (87 loc) · 2.58 KB
/
codegen.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
gem 'json'
require 'json'
require 'erb'
# def pad_str(count, str)
# str.lines.map{|line| "#{" "*count}#{line.lstrip}" }.join()
# end
spec_file = 'amqp-rabbitmq-0.9.1.json'
SPEC = JSON.load(File.read(spec_file))
DOMAINS = Hash[SPEC["domains"]]
class SpecGenerator
def initialize(spec)
@spec = spec
modify_spec
end
def classes
@spec["classes"]
end
def class_id_and_method_id_to_name
@spec["classes"].flat_map do |klass|
klass["methods"].map do |method|
"(#{klass["id"]}, #{method["id"]}) => \"#{klass["name"]}.#{method["name"]}\""
end
end
end
def class_id_and_method_id_carries_content
@spec["classes"].flat_map do |klass|
klass["methods"].select{|m| m["content"] }.map do |method|
"(#{klass["id"]}, #{method["id"]}) => #{!!method["content"]}"
end
end
end
def get_binding
binding
end
private
def modify_spec
@spec["classes"].each do |klass|
if klass["properties"] && klass["properties"].any?
klass["properties_struct_name"] = "#{titleize(klass["name"])}Properties"
klass["properties_fields"] = klass["properties"].map do |argument|
[snake_name(argument["name"]), argument_type(argument)]
end
end
klass["methods"].each do |method|
method["method_name"] = camel_name titleize(method["name"])
method["fields"]= method["arguments"].map do |argument|
[snake_name(argument["name"]), argument_type(argument)]
end
end
end
end
def argument_type(argument)
argument["domain"] ? DOMAINS[argument["domain"]] : argument["type"]
end
def titleize(name)
"#{name[0].upcase}#{name[1..-1]}"
end
def snake_name(name)
name.tr("-","_").gsub(/^type$/, "_type")
end
# foo-bar => fooBar
def camel_name(klass)
klass.gsub(/(\-.)/){|c| c[1].upcase}
end
end
method_frame_methods = <<-EOF
fn method_name(method_frame: &MethodFrame) -> &'static str {
match (method_frame.class_id, method_frame.method_id) {
<% class_id_and_method_id_to_name.each do |m| -%>
<%= m %>,
<% end -%>
(_,_) => "UNKNOWN"
}
}
fn method_carries_content(method_frame: &MethodFrame) -> bool {
match (method_frame.class_id, method_frame.method_id) {
<% class_id_and_method_id_carries_content.each do |m| -%>
<%= m %>,
<% end -%>
(_,_) => false
}
}
EOF
erb = ERB.new(method_frame_methods, 0 , "<>-")
File.write('src/method_frame_methods.rs', erb.result(SpecGenerator.new(SPEC.clone).get_binding))
erb = ERB.new(File.read('codegen.erb'), 0 , "<>-")
puts erb.result(SpecGenerator.new(SPEC.clone).get_binding)