require 'active_support'
require 'active_support/core_ext'
require 'erb'
require 'camelizable'
require 'yaml'
class String
include Camelizable
def make_field
self.gsub(/\./, "_")
end
def make_name
if self == "type"
"r#type"
else
self
end
end
end
def make_body(body, results, array_name=nil)
body[:properties].each do |it|
if it[:type] == "object"
make_body(it, results)
elsif it[:type] == "array" && it[:items][:type] == "object"
make_body(it[:items], results, it[:name].singularize)
elsif it[:type] == "enum_single"
results << make_expantions(it)
end
end
name = array_name || body[:name] || "body"
properties = body[:properties]
erb = ERB.new(File.read("body.erb"))
results << erb.result(binding)
end
def make_expantions(it)
@expantion_flag = true
class_name = it[:name].make_field.ucc
src = it[:value]
ary = src.split(", ")
all_flag = it[:type] == "enum"
use_flag = false
methods = []
erb = ERB.new(File.read("expantions.erb"))
erb.result(binding)
end
def execute(path)
@expantion_flag = false
m = /api\/(.+)\.yaml/.match(path)
name = m[1]
yml = YAML.load_file(path).deep_symbolize_keys
paths = (yml[:paths] || []).map{|it| it[:required] = "true"; it }
queries = yml[:queries] || []
form = yml[:form] || []
enum_flag = queries.filter{|it| it[:type] == "enum"}.present?
@date_flag = queries.filter{|it| it[:type] == "date" }.present?
self_required = (queries + form.filter{|it| it[:alter].blank?}).filter{|it| it[:required] } + paths
required_queries = queries.filter{|it| it[:required] }
non_required_queries = queries.filter{|it| !it[:required] }
fields = queries.filter{|it| /\.fields$/ =~ it[:name]}
auth = if yml[:auth] == "basic"
{
method: ".basic_auth(self.api_key_code, Some(self.api_secret_code))",
keys: ["api_key_code", "api_secret_code"],
}
else
{
method: ".bearer_auth(self.bearer_code)",
keys: ["bearer_code"],
}
end
expantions = (queries + form).filter{|it| (it[:type] == "enum" || it[:type] == "enum_single") && !(/\.fields$/ =~ it[:name]) }.map do |it|
make_expantions(it)
end
bodies = []
make_body(yml[:body], bodies) if yml[:body].present?
response_list = []
responses, refs, map = make_response("response", yml.dig(:response, :properties), false)
response_list << responses if responses.present?
if map.present?
map.each_pair do |key, value|
responses, _, _ = make_response(key.to_s, value.dig(:properties), false)
response_list << responses
end
end
serde_flag = @expantion_flag || bodies.present? || response_list.present?
api_struct = ERB.new(File.read("api_struct.erb")).result(binding)
api_new = ERB.new(File.read("api_new.erb")).result(binding).gsub(/^/, " ")
setter = ERB.new(File.read("setter.erb")).result(binding).gsub(/^/, " ")
parameters = ERB.new(File.read("parameters.erb")).result(binding).gsub(/^/, " ")
erb = ERB.new(File.read("api.erb"))
File.write("../src/api/#{name}.rs", erb.result(binding))
end
def execute_expantions(path)
m = /fields\/(.+)\.yaml/.match(path)
name = m[1]
yml = YAML.load_file(path).deep_symbolize_keys
class_name = name.make_field.ucc + "Fields"
src = yml[:value]
ary = src.split(", ")
all_flag = true
use_flag = true
methods = yml[:methods] || []
erb = ERB.new(File.read("expantions.erb"))
File.write("../src/fields/#{name}_fields.rs", erb.result(binding))
end
def calc_refs(name, properties, refs)
properties.each_pair do |key, value|
if value[:type] == "object"
if value[:ref].present? && value[:ref] != name.to_s
refs << value[:ref]
elsif value[:properties].present?
calc_refs(key, value[:properties], refs)
end
elsif value[:type] == "array" && value[:items][:type] == "object" && value[:items][:ref] != name.to_s
refs << value[:items][:ref]
end
end
end
def make_response(name, properties, independence_flag)
return ["", [], {}] if properties.blank?
refs = []
@enums = {}
@inner_map = {}
calc_refs(name, properties, refs)
refs.uniq!
class_name = name.make_field.ucc
erb = ERB.new(File.read("responses.erb"))
[erb.result(binding), refs, @inner_map]
end
def execute_responses(path)
@date_flag = false
m = /responses\/(.+)\.yaml/.match(path)
name = m[1]
yml = YAML.load_file(path).deep_symbolize_keys
properties = yml[:response][:properties]
independence_flag = true
res, refs, map = make_response(name, properties, independence_flag)
map.deep_dup.each_pair do |key, value|
responses, _, _ = make_response(key.to_s, value.dig(:properties), false)
res = res + "\n" + responses
end
File.write("../src/responses/#{name}.rs", res.gsub(/USE_DATE/, @date_flag ? "\nuse chrono::prelude::*;" : ""))
end
Dir.glob('api/*.yaml').each do |path|
execute(path)
end
Dir.glob('fields/*.yaml').each do |path|
execute_expantions(path)
end
Dir.glob('responses/*.yaml').each do |path|
execute_responses(path)
end