Skip to content

Commit 6b7aaea

Browse files
committed
feat(swagger-object) : Improve object creation
Add creation of Swagger::Object by some object instance (Related to #18)
1 parent c94b4cd commit 6b7aaea

3 files changed

Lines changed: 100 additions & 0 deletions

File tree

spec/swagger/object_spec.cr

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
require "../spec_helper"
2+
struct Project
3+
property id, name, description, vcs, open_source
4+
5+
def initialize(@id : Int32, @name : String, @vcs : String, @open_source : Bool, @description : String? = nil)
6+
end
7+
end
28

39
describe Swagger::Object do
410
describe "#new" do
@@ -41,5 +47,24 @@ describe Swagger::Object do
4147
raw.properties.should be_nil
4248
raw.items.should eq("Comment")
4349
end
50+
51+
it "should generate schema of object from object instance" do
52+
raw = Swagger::Object.create_from_instance(
53+
Project.new(1, "swagger", "git", true, "Swagger contains a OpenAPI / Swagger universal documentation generator and HTTP server handler.")
54+
)
55+
raw.name.should eq "Project"
56+
raw.type.should eq "object"
57+
raw.properties.should eq [
58+
Swagger::Property.new("id", "integer", "int32", example: 1, required: true),
59+
Swagger::Property.new("name", example: "swagger", required: true),
60+
Swagger::Property.new("vcs", example: "git", required: true),
61+
Swagger::Property.new("open_source", "boolean", example: true, required: true),
62+
Swagger::Property.new(
63+
"description",
64+
example: "Swagger contains a OpenAPI / Swagger universal documentation generator and HTTP server handler.",
65+
required: false
66+
),
67+
]
68+
end
4469
end
4570
end

src/swagger/object.cr

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,32 @@ module Swagger
2121
def initialize(@name : String, @type : String, @properties : Array(Property)? = nil,
2222
@items : (self | String)? = nil)
2323
end
24+
25+
def self.create_from_instance(reflecting instance : T, custom_name : String? = nil) forall T
26+
{% begin %}
27+
properties = [] of Property
28+
{% for ivar in T.instance.instance_vars %}
29+
{{ iname = ivar.name.stringify }}
30+
swagger_data_type = Utils::SwaggerDataType.create_from_class({{ ivar.type }})
31+
{{ irequired = !ivar.type.union? }}
32+
value = {% if T.class? || T.struct? %} instance.{{ ivar.name }} {% else %} {{ ivar.default_value.stringify }} {% end %}
33+
properties << Property.new(
34+
{{ iname }},
35+
swagger_data_type.type,
36+
format: swagger_data_type.format,
37+
{% if ivar.type <= String || ivar.type <= Int32 ||
38+
ivar.type <= Int64 || ivar.type <= Float64 ||
39+
ivar.type <= Bool %}
40+
example: value,
41+
{% else %}
42+
example: value.to_s,
43+
{% end %}
44+
required: {{ irequired }}
45+
)
46+
{% end %}
47+
48+
self.new(custom_name ? custom_name.as(String) : instance.class.name, "object", properties)
49+
{% end %}
50+
end
2451
end
2552
end

src/swagger/utils.cr

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
module Utils
2+
struct SwaggerDataType
3+
property type : String
4+
property format : String?
5+
6+
def initialize(@type : String, @format : String?)
7+
end
8+
9+
def self.create_from_class(type : T.class) forall T
10+
{% begin %}
11+
{% if T.union? %}
12+
return self.create_from_class({{ T.union_types.find { |var| var != Nil } }})
13+
{% else %}
14+
# Cf https://swagger.io/specification/#data-types
15+
{% if T <= String || T <= Nil %}
16+
swagger_type = "string"
17+
swagger_format = nil
18+
{% elsif T <= Int %}
19+
swagger_type = "integer"
20+
{% if T <= Int32 %}
21+
swagger_format = "int32"
22+
{% elsif T <= Int64 %}
23+
swagger_format = "int64"
24+
{% else %}
25+
swagger_format = nil
26+
{% end %}
27+
{% elsif T <= Number %}
28+
swagger_type = "number"
29+
{% if T <= Float32 %}
30+
swagger_format = "float"
31+
{% elsif T <= Float64 %}
32+
swagger_format = "double"
33+
{% else %}
34+
swagger_format = nil
35+
{% end %}
36+
{% elsif T <= Bool %}
37+
swagger_type = "boolean"
38+
swagger_format = nil
39+
{% else %}
40+
swagger_type = {{ T.stringify }}
41+
swagger_format = nil
42+
{% end %}
43+
return self.new(swagger_type, swagger_format)
44+
{% end %}
45+
{% end %}
46+
end
47+
end
48+
end

0 commit comments

Comments
 (0)