Skip to content

Commit a40dc56

Browse files
authored
[CRYSTAL] object_id method should be a reserved words (#22577)
* style(crystal): fix coding style * fix(crystal): object_id is so central in Crystal that it should not be overridden by user code See: https://crystal-lang.org/api/1.18.2/Reference.html#object_id%3AUInt64-instance-method * style(crystal): fix coding style * fix(crystal): fix partial_oneof_module by using a class instead of a module Fix #22563 * fix(crystal): remove non-working code It's not working because it uses #send method which doesn't exist in Crystal See: https://crystal-lang.org/reference/1.18/crystal_for_rubyists/metaprogramming_help.html#differences-between-ruby-and-crystal * fix(crystal): update reserved words, separate reserved keywords from methods * fix(crystal): update samples * fix(crystal): set default values when options are not passed * fix(crystal): follow up #22545 * fix(crystal): remove travis.yml file * style(crystal): fix coding style * style(crystal): use kwargs when calling @api_client * style(crystal): use kwargs when calling Crest::Request.new * fix(crystal): remove useless return_type argument * fix(crystal): map object type to JSON::Any type * fix(crystal): reduce use of require * fix(crystal): return early if value is nil * fix(crystal): update doc * fix(crystal): remove dead code * fix(crystal): kemal is not used in specs * fix(crystal): class name should be in PascalCase Fix: - class EnumAttributeValidatorFor_type < EnumAttributeValidator + class EnumAttributeValidatorForType < EnumAttributeValidator * fix(crystal): fix ameba warnings
1 parent 7af1d02 commit a40dc56

File tree

30 files changed

+546
-1206
lines changed

30 files changed

+546
-1206
lines changed

docs/generators/crystal.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,17 +94,19 @@ These options may be applied as additional-properties (cli) or configOptions (pl
9494
<li>if</li>
9595
<li>in</li>
9696
<li>include</li>
97-
<li>instance</li>
97+
<li>instance_sizeof</li>
9898
<li>is_a?</li>
9999
<li>lib</li>
100100
<li>macro</li>
101101
<li>module</li>
102102
<li>next</li>
103103
<li>nil</li>
104104
<li>nil?</li>
105+
<li>object_id</li>
105106
<li>of</li>
106107
<li>out</li>
107108
<li>pointerof</li>
109+
<li>previous_def</li>
108110
<li>private</li>
109111
<li>protected</li>
110112
<li>require</li>

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CrystalClientCodegen.java

Lines changed: 78 additions & 71 deletions
Large diffs are not rendered by default.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.openapitools.codegen.templating.mustache;
18+
19+
import com.samskivert.mustache.Mustache;
20+
import com.samskivert.mustache.Template;
21+
import org.openapitools.codegen.utils.CamelizeOption;
22+
23+
import java.io.IOException;
24+
import java.io.Writer;
25+
26+
import static org.openapitools.codegen.utils.StringUtils.camelize;
27+
28+
/**
29+
* Converts text in a fragment to PascalCase.
30+
* <p>
31+
* Register:
32+
* <pre>
33+
* additionalProperties.put("pascalcase", new PascalCaseLambda());
34+
* </pre>
35+
* <p>
36+
* Use:
37+
* <pre>
38+
* {{#pascalcase}}{{name}}{{/pascalcase}}
39+
* </pre>
40+
*/
41+
public class PascalCaseLambda implements Mustache.Lambda {
42+
public PascalCaseLambda() {
43+
}
44+
45+
@Override
46+
public void execute(Template.Fragment fragment, Writer writer) throws IOException {
47+
String text = fragment.execute();
48+
text = camelize(text);
49+
writer.write(text);
50+
}
51+
}

modules/openapi-generator/src/main/resources/crystal/api.mustache

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -159,25 +159,25 @@ module {{moduleName}}
159159
# http body (model)
160160
post_body = {{#bodyParam}}{{{paramName}}}.to_json{{/bodyParam}}{{^bodyParam}}nil{{/bodyParam}}
161161

162-
# return_type
163-
return_type = {{#returnType}}"{{{.}}}"{{/returnType}}{{^returnType}}nil{{/returnType}}
164-
165162
# auth_names
166163
auth_names = {{#authMethods}}{{#-first}}[{{/-first}}"{{name}}"{{^-last}}, {{/-last}}{{#-last}}]{{/-last}}{{/authMethods}}{{^authMethods}}[] of String{{/authMethods}}
167164

168-
data, status_code, headers = @api_client.call_api(:{{httpMethod}},
169-
local_var_path,
170-
:"{{classname}}.{{operationId}}",
171-
return_type,
172-
post_body,
173-
auth_names,
174-
header_params,
175-
query_params,
176-
cookie_params,
177-
form_params)
165+
data, status_code, headers = @api_client.call_api(
166+
http_method: :{{httpMethod}},
167+
path: local_var_path,
168+
operation: :"{{classname}}.{{operationId}}",
169+
post_body: post_body,
170+
auth_names: auth_names,
171+
header_params: header_params,
172+
query_params: query_params,
173+
cookie_params: cookie_params,
174+
form_params: form_params
175+
)
176+
178177
if @api_client.config.debugging
179178
Log.debug {"API called: {{classname}}#{{operationId}}\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"}
180179
end
180+
181181
return {{#returnType}}{{{.}}}.from_json(data){{/returnType}}{{^returnType}}nil{{/returnType}}, status_code, headers
182182
end
183183
{{^-last}}

modules/openapi-generator/src/main/resources/crystal/api_client.mustache

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ module {{moduleName}}
119119
#
120120
# @return [Array<(Object, Integer, Hash)>] an array of 3 elements:
121121
# the data deserialized from response body (could be nil), response status code and response headers.
122-
def call_api(http_method : Symbol, path : String, operation : Symbol, return_type : String?, post_body : String?, auth_names = [] of String, header_params = {} of String => String, query_params = {} of String => String, cookie_params = {} of String => String, form_params = {} of Symbol => (String | ::File))
122+
def call_api(http_method : Symbol, path : String, operation : Symbol, post_body : String?, auth_names = [] of String, header_params = {} of String => String, query_params = {} of String => String, cookie_params = {} of String => String, form_params = {} of Symbol => (String | ::File))
123123
#ssl_options = {
124124
# :ca_file => @config.ssl_ca_file,
125125
# :verify => @config.ssl_verify,
@@ -139,8 +139,9 @@ module {{moduleName}}
139139
form_or_body = form_params
140140
end
141141

142-
request = Crest::Request.new(http_method,
143-
build_request_url(path, operation),
142+
request = Crest::Request.new(
143+
method: http_method,
144+
url: build_request_url(path, operation),
144145
params: query_params,
145146
headers: header_params,
146147
cookies: cookie_params,

modules/openapi-generator/src/main/resources/crystal/base_object.mustache

Lines changed: 2 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,3 @@
1-
# Builds the object from hash
2-
# @param [Hash] attributes Model attributes in the form of hash
3-
# @return [Object] Returns the model itself
4-
def self.build_from_hash(attributes)
5-
new.build_from_hash(attributes)
6-
end
7-
8-
# Builds the object from hash
9-
# @param [Hash] attributes Model attributes in the form of hash
10-
# @return [Object] Returns the model itself
11-
def build_from_hash(attributes)
12-
return nil unless attributes.is_a?(Hash)
13-
{{#parent}}
14-
super(attributes)
15-
{{/parent}}
16-
self.class.openapi_types.each_pair do |key, type|
17-
if !attributes[self.class.attribute_map[key]]? && self.class.openapi_nullable.includes?(key)
18-
self.send("#{key}=", nil)
19-
elsif type =~ /\AArray<(.*)>/i
20-
# check to ensure the input is an array given that the attribute
21-
# is documented as an array but the input is not
22-
if attributes[self.class.attribute_map[key]].is_a?(Array)
23-
self.send("#{key}=", attributes[self.class.attribute_map[key]].map { |v| _deserialize($1, v) })
24-
end
25-
elsif !attributes[self.class.attribute_map[key]].nil?
26-
self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]]))
27-
end
28-
end
29-
30-
self
31-
end
32-
33-
# Deserializes the data based on type
34-
# @param string type Data type
35-
# @param string value Value to be deserialized
36-
# @return [Object] Deserialized data
37-
def _deserialize(type, value)
38-
case type.to_sym
39-
when :Time
40-
Time.parse(value)
41-
when :Date
42-
Date.parse(value)
43-
when :String
44-
value.to_s
45-
when :Integer
46-
value.to_i
47-
when :Float
48-
value.to_f
49-
when :Boolean
50-
if value.to_s =~ /\A(true|t|yes|y|1)\z/i
51-
true
52-
else
53-
false
54-
end
55-
when :Object
56-
# generic object (usually a Hash), return directly
57-
value
58-
when /\AArray<(?<inner_type>.+)>\z/
59-
inner_type = Regexp.last_match[:inner_type]
60-
value.map { |v| _deserialize(inner_type, v) }
61-
when /\AHash<(?<k_type>.+?), (?<v_type>.+)>\z/
62-
k_type = Regexp.last_match[:k_type]
63-
v_type = Regexp.last_match[:v_type]
64-
({} of Symbol => String).tap do |hash|
65-
value.each do |k, v|
66-
hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
67-
end
68-
end
69-
else # model
70-
# models (e.g. Pet) or oneOf
71-
klass = {{moduleName}}.const_get(type)
72-
klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
73-
end
74-
end
75-
761
# Returns the string representation of the object
772
# @return [String] String presentation of the object
783
def to_s
@@ -100,6 +25,8 @@
10025
# @param [Object] value Any valid value
10126
# @return [Hash] Returns the value in the form of hash
10227
private def _to_h(value)
28+
return nil if value.nil?
29+
10330
if value.is_a?(Hash)
10431
hash = NetboxClient::RecursiveHash.new
10532
value.each { |k, v| hash[k] = _to_h(v) }

modules/openapi-generator/src/main/resources/crystal/model.mustache

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
# {{#lambdaPrefixWithHash}}{{> api_info}}{{/lambdaPrefixWithHash}}
22

3-
require "big"
4-
require "json"
5-
require "yaml"
6-
require "time"
7-
83
module {{moduleName}}
94
{{#models}}
105
{{#model}}

modules/openapi-generator/src/main/resources/crystal/partial_model_generic.mustache

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
{{#vars}}
5757
{{#isEnum}}
5858
{{^isContainer}}
59-
class EnumAttributeValidatorFor{{#lambdaTitlecase}}{{{name}}}{{/lambdaTitlecase}} < EnumAttributeValidator
59+
class EnumAttributeValidatorFor{{#lambdaPascalcase}}{{{name}}}{{/lambdaPascalcase}} < EnumAttributeValidator
6060
@attribute : String
6161
@allowable_values : Array(Int32 | Int64 | Float32 | Float64 | String)
6262

@@ -118,7 +118,7 @@
118118
{{#vars}}
119119
{{#isEnum}}
120120
{{^isContainer}}
121-
{{{name}}}_validator = EnumAttributeValidatorFor{{#lambdaTitlecase}}{{{name}}}{{/lambdaTitlecase}}.new
121+
{{{name}}}_validator = EnumAttributeValidatorFor{{#lambdaPascalcase}}{{{name}}}{{/lambdaPascalcase}}.new
122122
if !{{{name}}}_validator.valid?(@{{{name}}})
123123
message = {{{name}}}_validator.message
124124
invalid_properties.push(message)
@@ -181,7 +181,7 @@
181181
{{#vars}}
182182
{{#isEnum}}
183183
{{^isContainer}}
184-
{{{name}}}_validator = EnumAttributeValidatorFor{{#lambdaTitlecase}}{{{name}}}{{/lambdaTitlecase}}.new
184+
{{{name}}}_validator = EnumAttributeValidatorFor{{#lambdaPascalcase}}{{{name}}}{{/lambdaPascalcase}}.new
185185
return false unless {{{name}}}_validator.valid?(@{{{name}}})
186186
{{/isContainer}}
187187
{{/isEnum}}
@@ -234,7 +234,7 @@
234234
# Custom attribute writer method checking allowed values (enum).
235235
# @param [Object] {{{name}}} Object to be assigned
236236
def {{{name}}}=({{{name}}})
237-
validator = EnumAttributeValidatorFor{{#lambdaTitlecase}}{{{name}}}{{/lambdaTitlecase}}.new
237+
validator = EnumAttributeValidatorFor{{#lambdaPascalcase}}{{{name}}}{{/lambdaPascalcase}}.new
238238
unless validator.valid?({{{name}}})
239239
raise ArgumentError.new(validator.message)
240240
end

0 commit comments

Comments
 (0)