Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import org.openapitools.codegen.model.OperationMap;
import org.openapitools.codegen.model.OperationsMap;
import org.openapitools.codegen.templating.mustache.PrefixWithHashLambda;
import org.openapitools.codegen.templating.mustache.UppercaseLambda;
import org.openapitools.codegen.templating.mustache.TitlecaseLambda;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -284,6 +286,7 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("api_error.mustache", shardFolder, "api_error.cr"));
supportingFiles.add(new SupportingFile("configuration.mustache", shardFolder, "configuration.cr"));
supportingFiles.add(new SupportingFile("api_client.mustache", shardFolder, "api_client.cr"));
supportingFiles.add(new SupportingFile("recursive_hash.mustache", shardFolder, "recursive_hash.cr"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
Expand All @@ -296,6 +299,8 @@ public void processOpts() {

// add lambda for mustache templates
additionalProperties.put("lambdaPrefixWithHash", new PrefixWithHashLambda());
additionalProperties.put("lambdaUppercase", new UppercaseLambda());
additionalProperties.put("lambdaTitlecase", new TitlecaseLambda());

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,44 +76,38 @@
# Returns the string representation of the object
# @return [String] String presentation of the object
def to_s
to_hash.to_s
to_h.to_s
end

# to_body is an alias to to_hash (backward compatibility)
# to_body is an alias to to_h (backward compatibility)
# @return [Hash] Returns the object in the form of hash
def to_body
to_hash
to_h
end

# Returns the object in the form of hash
# @return [Hash] Returns the object in the form of hash
def to_hash
hash = {{^parent}}{} of Symbol => String{{/parent}}{{#parent}}super{{/parent}}
self.class.attribute_map.each_pair do |attr, param|
value = self.send(attr)
if value.nil?
is_nullable = self.class.openapi_nullable.includes?(attr)
next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
end

hash[param] = _to_hash(value)
end
hash
def to_h
hash = NetboxClient::RecursiveHash.new
{{#vars}}
hash["{{{baseName}}}"] = _to_h({{{name}}})
{{/vars}}
hash.to_h
end

# Outputs non-array value in the form of hash
# For object, use to_hash. Otherwise, just return the value
# For object, use to_h. Otherwise, just return the value
# @param [Object] value Any valid value
# @return [Hash] Returns the value in the form of hash
def _to_hash(value)
if value.is_a?(Array)
value.compact.map { |v| _to_hash(v) }
elsif value.is_a?(Hash)
({} of Symbol => String).tap do |hash|
value.each { |k, v| hash[k] = _to_hash(v) }
end
elsif value.respond_to? :to_hash
value.to_hash
private def _to_h(value)
if value.is_a?(Hash)
hash = NetboxClient::RecursiveHash.new
value.each { |k, v| hash[k] = _to_h(v) }
hash
elsif value.is_a?(Array)
value.compact.map { |v| _to_h(v) }
elsif value.responds_to?(:to_h)
value.to_h
else
value
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,48 @@

{{/optionalVars}}
{{#hasEnums}}
class EnumAttributeValidator
getter datatype : String
getter allowable_values : Array(String)

def initialize(datatype, allowable_values)
@datatype = datatype
@allowable_values = allowable_values.map do |value|
case datatype.to_s
when /Integer/i
value.to_i
when /Float/i
value.to_f
else
value
end
abstract class EnumAttributeValidator
def valid?(value)
!value || @allowable_values.includes?(value)
end

def message
"invalid value for \"#{@attribute}\", must be one of #{@allowable_values}."
end

def to(_type, value)
case _type
when Int32
value.to_i32
when Int64
value.to_i64
when Float32
value.to_f32
when Float64
value.to_f64
else
value.to_s
end
end
end

def valid?(value)
!value || allowable_values.includes?(value)
{{#vars}}
{{#isEnum}}
{{^isContainer}}
class EnumAttributeValidatorFor{{#lambdaTitlecase}}{{{name}}}{{/lambdaTitlecase}} < EnumAttributeValidator
@attribute : String
@allowable_values : Array(Int32 | Int64 | Float32 | Float64 | String)

def initialize
@attribute = "{{{name}}}"
@allowable_values = [{{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}].map { |value| to({{{dataType}}}, value)}
end
end

{{/isContainer}}
{{/isEnum}}
{{/vars}}

{{/hasEnums}}
{{#anyOf}}
{{#-first}}
Expand Down Expand Up @@ -89,54 +108,64 @@
{{/discriminator}}
# Initializes the object
# @param [Hash] attributes Model attributes in the form of hash
def initialize({{#requiredVars}}@{{{name}}} : {{{dataType}}}{{^-last}}, {{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}}, {{/hasOptional}}{{/hasRequired}}{{#optionalVars}}@{{{name}}} : {{{dataType}}}?{{^-last}}, {{/-last}}{{/optionalVars}})
def initialize({{#requiredVars}}@{{{name}}} : {{{dataType}}}{{^-last}}, {{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}}, {{/hasOptional}}{{/hasRequired}}{{#optionalVars}}@{{{name}}} : {{{dataType}}}? = nil{{^-last}}, {{/-last}}{{/optionalVars}})
end

# Show invalid properties with the reasons. Usually used together with valid?
# @return Array for valid properties with the reasons
def list_invalid_properties
invalid_properties = {{^parent}}Array(String).new{{/parent}}{{#parent}}super{{/parent}}
{{#vars}}
{{#isEnum}}
{{^isContainer}}
{{{name}}}_validator = EnumAttributeValidatorFor{{#lambdaTitlecase}}{{{name}}}{{/lambdaTitlecase}}.new
if !{{{name}}}_validator.valid?(@{{{name}}})
message = {{{name}}}_validator.message
invalid_properties.push(message)
end

{{/isContainer}}
{{/isEnum}}
{{#hasValidation}}
{{#maxLength}}
if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.to_s.size > {{{maxLength}}}
if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.try &.to_s.try &.size.try &.> {{{maxLength}}}
invalid_properties.push("invalid value for \"{{{name}}}\", the character length must be smaller than or equal to {{{maxLength}}}.")
end

{{/maxLength}}
{{#minLength}}
if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.to_s.size < {{{minLength}}}
if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.try &.to_s.try &.size.try &.< {{{minLength}}}
invalid_properties.push("invalid value for \"{{{name}}}\", the character length must be greater than or equal to {{{minLength}}}.")
end

{{/minLength}}
{{#maximum}}
if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}} >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{{maximum}}}
if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.try &.>{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{{maximum}}}
invalid_properties.push("invalid value for \"{{{name}}}\", must be smaller than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}{{{maximum}}}.")
end

{{/maximum}}
{{#minimum}}
if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}} <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{{minimum}}}
if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.try &.<{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{{minimum}}}
invalid_properties.push("invalid value for \"{{{name}}}\", must be greater than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}{{{minimum}}}.")
end

{{/minimum}}
{{#pattern}}
pattern = Regexp.new({{{pattern}}})
if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}} !~ pattern
pattern = {{{pattern}}}
if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.try &.!~ pattern
invalid_properties.push("invalid value for \"{{{name}}}\", must conform to the pattern #{pattern}.")
end

{{/pattern}}
{{#maxItems}}
if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.size > {{{maxItems}}}
if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.try &.size.try &.> {{{maxItems}}}
invalid_properties.push("invalid value for \"{{{name}}}\", number of items must be less than or equal to {{{maxItems}}}."
end

{{/maxItems}}
{{#minItems}}
if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.size < {{{minItems}}}
if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.try &.size.try &.< {{{minItems}}}
invalid_properties.push("invalid value for \"{{{name}}}\", number of items must be greater than or equal to {{{minItems}}}."
end

Expand All @@ -152,39 +181,39 @@
{{#vars}}
{{#isEnum}}
{{^isContainer}}
{{{name}}}_validator = EnumAttributeValidator.new("{{{dataType}}}", [{{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}])
{{{name}}}_validator = EnumAttributeValidatorFor{{#lambdaTitlecase}}{{{name}}}{{/lambdaTitlecase}}.new
return false unless {{{name}}}_validator.valid?(@{{{name}}})
{{/isContainer}}
{{/isEnum}}
{{#hasValidation}}
{{#maxLength}}
return false if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.to_s.size > {{{maxLength}}}
return false if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.try &.to_s.try &.size.try &.> {{{maxLength}}}
{{/maxLength}}
{{#minLength}}
return false if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.to_s.size < {{{minLength}}}
return false if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.try &.to_s.try &.size.try &.< {{{minLength}}}
{{/minLength}}
{{#maximum}}
return false if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}} >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{{maximum}}}
return false if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.try &.>{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{{maximum}}}
{{/maximum}}
{{#minimum}}
return false if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}} <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{{minimum}}}
return false if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.try &.<{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{{minimum}}}
{{/minimum}}
{{#pattern}}
return false if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}} !~ Regexp.new({{{pattern}}})
return false if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.try &.!~ {{{pattern}}}
{{/pattern}}
{{#maxItems}}
return false if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.size > {{{maxItems}}}
return false if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.try &.size.try &.> {{{maxItems}}}
{{/maxItems}}
{{#minItems}}
return false if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.size < {{{minItems}}}
return false if {{^required}}!@{{{name}}}.nil? && {{/required}}@{{{name}}}.try &.size.try &.< {{{minItems}}}
{{/minItems}}
{{/hasValidation}}
{{/vars}}
{{#anyOf}}
{{#-first}}
_any_of_found = false
self.class.openapi_any_of.each do |_class|
_any_of = {{moduleName}}.const_get(_class).build_from_hash(self.to_hash)
_any_of = {{moduleName}}.const_get(_class).build_from_hash(self.to_h)
if _any_of.valid?
_any_of_found = true
end
Expand All @@ -205,9 +234,9 @@
# Custom attribute writer method checking allowed values (enum).
# @param [Object] {{{name}}} Object to be assigned
def {{{name}}}=({{{name}}})
validator = EnumAttributeValidator.new("{{{dataType}}}", [{{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}])
validator = EnumAttributeValidatorFor{{#lambdaTitlecase}}{{{name}}}{{/lambdaTitlecase}}.new
unless validator.valid?({{{name}}})
raise ArgumentError.new("invalid value for \"{{{name}}}\", must be one of #{validator.allowable_values}.")
raise ArgumentError.new(validator.message)
end
@{{{name}}} = {{{name}}}
end
Expand Down Expand Up @@ -244,7 +273,7 @@

{{/minimum}}
{{#pattern}}
pattern = Regexp.new({{{pattern}}})
pattern = {{{pattern}}}
if {{^required}}!{{{name}}}.nil? && {{/required}}{{{name}}} !~ pattern
raise ArgumentError.new("invalid value for \"{{{name}}}\", must conform to the pattern #{pattern}.")
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module {{moduleName}}
# Define possible value types for our own AnyHash class (RecursiveHash)
alias ValuesType = Nil |
Bool |
String |
Time |
Int32 |
Int64 |
Float32 |
Float64 |
Array(ValuesType)

# Define our own AnyHash class (RecursiveHash)
# RecursiveHash
AnyHash.define_new klass: :RecursiveHash,
key: String,
value: ValuesType
end
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ description: |
- {{{ shardDescription}}}
crystal: ">= 0.35.1"
dependencies:
any_hash:
github: Sija/any_hash.cr
crest:
github: mamantoha/crest
version: ~> 1.3.13
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# {{#lambdaPrefixWithHash}}{{> api_info}}{{/lambdaPrefixWithHash}}

# Dependencies
require "any_hash"
require "crest"
require "log"

Expand Down
1 change: 1 addition & 0 deletions samples/client/petstore/crystal/.openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ src/petstore/models/order.cr
src/petstore/models/pet.cr
src/petstore/models/tag.cr
src/petstore/models/user.cr
src/petstore/recursive_hash.cr
2 changes: 2 additions & 0 deletions samples/client/petstore/crystal/shard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ description: |
-
crystal: ">= 0.35.1"
dependencies:
any_hash:
github: Sija/any_hash.cr
crest:
github: mamantoha/crest
version: ~> 1.3.13
Expand Down
1 change: 1 addition & 0 deletions samples/client/petstore/crystal/src/petstore.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#

# Dependencies
require "any_hash"
require "crest"
require "log"

Expand Down
Loading
Loading