diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CrystalClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CrystalClientCodegen.java index 42ed65816e85..5725718d1866 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CrystalClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CrystalClientCodegen.java @@ -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; @@ -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")); @@ -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()); } diff --git a/modules/openapi-generator/src/main/resources/crystal/base_object.mustache b/modules/openapi-generator/src/main/resources/crystal/base_object.mustache index 22dafd411205..1256b0bfc53f 100644 --- a/modules/openapi-generator/src/main/resources/crystal/base_object.mustache +++ b/modules/openapi-generator/src/main/resources/crystal/base_object.mustache @@ -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 diff --git a/modules/openapi-generator/src/main/resources/crystal/partial_model_generic.mustache b/modules/openapi-generator/src/main/resources/crystal/partial_model_generic.mustache index 6843bf2f16ca..791a2084ddda 100644 --- a/modules/openapi-generator/src/main/resources/crystal/partial_model_generic.mustache +++ b/modules/openapi-generator/src/main/resources/crystal/partial_model_generic.mustache @@ -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}} @@ -89,7 +108,7 @@ {{/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? @@ -97,46 +116,56 @@ 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 @@ -152,31 +181,31 @@ {{#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}} @@ -184,7 +213,7 @@ {{#-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 @@ -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 @@ -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 diff --git a/modules/openapi-generator/src/main/resources/crystal/recursive_hash.mustache b/modules/openapi-generator/src/main/resources/crystal/recursive_hash.mustache new file mode 100644 index 000000000000..7d682f48af51 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/crystal/recursive_hash.mustache @@ -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 diff --git a/modules/openapi-generator/src/main/resources/crystal/shard.mustache b/modules/openapi-generator/src/main/resources/crystal/shard.mustache index 424f5397e164..6a1c86894e47 100644 --- a/modules/openapi-generator/src/main/resources/crystal/shard.mustache +++ b/modules/openapi-generator/src/main/resources/crystal/shard.mustache @@ -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 diff --git a/modules/openapi-generator/src/main/resources/crystal/shard_name.mustache b/modules/openapi-generator/src/main/resources/crystal/shard_name.mustache index 6d2de8333a37..16e645c5e66c 100644 --- a/modules/openapi-generator/src/main/resources/crystal/shard_name.mustache +++ b/modules/openapi-generator/src/main/resources/crystal/shard_name.mustache @@ -1,6 +1,7 @@ # {{#lambdaPrefixWithHash}}{{> api_info}}{{/lambdaPrefixWithHash}} # Dependencies +require "any_hash" require "crest" require "log" diff --git a/samples/client/petstore/crystal/.openapi-generator/FILES b/samples/client/petstore/crystal/.openapi-generator/FILES index 46d1bf5974e7..30a8f1ce4b53 100644 --- a/samples/client/petstore/crystal/.openapi-generator/FILES +++ b/samples/client/petstore/crystal/.openapi-generator/FILES @@ -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 diff --git a/samples/client/petstore/crystal/shard.yml b/samples/client/petstore/crystal/shard.yml index 61c0b4f651dc..583b30f688ab 100644 --- a/samples/client/petstore/crystal/shard.yml +++ b/samples/client/petstore/crystal/shard.yml @@ -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 diff --git a/samples/client/petstore/crystal/src/petstore.cr b/samples/client/petstore/crystal/src/petstore.cr index ead1161d59ec..bfc05276512e 100644 --- a/samples/client/petstore/crystal/src/petstore.cr +++ b/samples/client/petstore/crystal/src/petstore.cr @@ -9,6 +9,7 @@ # # Dependencies +require "any_hash" require "crest" require "log" diff --git a/samples/client/petstore/crystal/src/petstore/models/another_property_name_mapping.cr b/samples/client/petstore/crystal/src/petstore/models/another_property_name_mapping.cr index a1082dc9ed2b..237ba3a2677f 100644 --- a/samples/client/petstore/crystal/src/petstore/models/another_property_name_mapping.cr +++ b/samples/client/petstore/crystal/src/petstore/models/another_property_name_mapping.cr @@ -33,7 +33,7 @@ module Petstore # Initializes the object # @param [Hash] attributes Model attributes in the form of hash - def initialize(@http_debug_operation : String?, @underscore_type : String?, @_type : String?, @type_with_underscore : String?) + def initialize(@http_debug_operation : String? = nil, @underscore_type : String? = nil, @_type : String? = nil, @type_with_underscore : String? = nil) end # Show invalid properties with the reasons. Usually used together with valid? @@ -147,44 +147,39 @@ module Petstore # 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 = {} of Symbol => String - 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 + hash["http_debug_operation"] = _to_h(http_debug_operation) + hash["_type"] = _to_h(underscore_type) + hash["type"] = _to_h(_type) + hash["type_"] = _to_h(type_with_underscore) + 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 diff --git a/samples/client/petstore/crystal/src/petstore/models/api_response.cr b/samples/client/petstore/crystal/src/petstore/models/api_response.cr index ee7a2499c414..1a553198c7d9 100644 --- a/samples/client/petstore/crystal/src/petstore/models/api_response.cr +++ b/samples/client/petstore/crystal/src/petstore/models/api_response.cr @@ -31,7 +31,7 @@ module Petstore # Initializes the object # @param [Hash] attributes Model attributes in the form of hash - def initialize(@code : Int32?, @_type : String?, @message : String?) + def initialize(@code : Int32? = nil, @_type : String? = nil, @message : String? = nil) end # Show invalid properties with the reasons. Usually used together with valid? @@ -144,44 +144,38 @@ module Petstore # 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 = {} of Symbol => String - 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 + hash["code"] = _to_h(code) + hash["type"] = _to_h(_type) + hash["message"] = _to_h(message) + 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 diff --git a/samples/client/petstore/crystal/src/petstore/models/category.cr b/samples/client/petstore/crystal/src/petstore/models/category.cr index 765fb5579176..2b62bd91cf86 100644 --- a/samples/client/petstore/crystal/src/petstore/models/category.cr +++ b/samples/client/petstore/crystal/src/petstore/models/category.cr @@ -28,15 +28,15 @@ module Petstore # Initializes the object # @param [Hash] attributes Model attributes in the form of hash - def initialize(@id : Int64?, @name : String?) + def initialize(@id : Int64? = nil, @name : String? = nil) 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 = Array(String).new - pattern = Regexp.new(/^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$/) - if !@name.nil? && @name !~ pattern + pattern = /^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$/ + if !@name.nil? && @name.try &.!~ pattern invalid_properties.push("invalid value for \"name\", must conform to the pattern #{pattern}.") end @@ -46,14 +46,14 @@ module Petstore # Check to see if the all the properties in the model are valid # @return true if the model is valid def valid? - return false if !@name.nil? && @name !~ Regexp.new(/^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$/) + return false if !@name.nil? && @name.try &.!~ /^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$/ true end # Custom attribute writer method with validation # @param [Object] name Value to be assigned def name=(name) - pattern = Regexp.new(/^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$/) + pattern = /^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$/ if !name.nil? && name !~ pattern raise ArgumentError.new("invalid value for \"name\", must conform to the pattern #{pattern}.") end @@ -157,44 +157,37 @@ module Petstore # 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 = {} of Symbol => String - 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 + hash["id"] = _to_h(id) + hash["name"] = _to_h(name) + 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 diff --git a/samples/client/petstore/crystal/src/petstore/models/format_test.cr b/samples/client/petstore/crystal/src/petstore/models/format_test.cr index 58069f10a32b..05d144937105 100644 --- a/samples/client/petstore/crystal/src/petstore/models/format_test.cr +++ b/samples/client/petstore/crystal/src/petstore/models/format_test.cr @@ -72,73 +72,73 @@ module Petstore # Initializes the object # @param [Hash] attributes Model attributes in the form of hash - def initialize(@number : Float64, @byte : String, @date : Time, @password : String, @integer : Int32?, @int32 : Int32?, @int64 : Int64?, @float : Float32?, @double : Float64?, @decimal : BigDecimal?, @string : String?, @binary : ::File?, @date_time : Time?, @uuid : String?, @pattern_with_digits : String?, @pattern_with_digits_and_delimiter : String?) + def initialize(@number : Float64, @byte : String, @date : Time, @password : String, @integer : Int32? = nil, @int32 : Int32? = nil, @int64 : Int64? = nil, @float : Float32? = nil, @double : Float64? = nil, @decimal : BigDecimal? = nil, @string : String? = nil, @binary : ::File? = nil, @date_time : Time? = nil, @uuid : String? = nil, @pattern_with_digits : String? = nil, @pattern_with_digits_and_delimiter : String? = nil) 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 = Array(String).new - if !@integer.nil? && @integer > 100 + if !@integer.nil? && @integer.try &.> 100 invalid_properties.push("invalid value for \"integer\", must be smaller than or equal to 100.") end - if !@integer.nil? && @integer < 10 + if !@integer.nil? && @integer.try &.< 10 invalid_properties.push("invalid value for \"integer\", must be greater than or equal to 10.") end - if !@int32.nil? && @int32 > 200 + if !@int32.nil? && @int32.try &.> 200 invalid_properties.push("invalid value for \"int32\", must be smaller than or equal to 200.") end - if !@int32.nil? && @int32 < 20 + if !@int32.nil? && @int32.try &.< 20 invalid_properties.push("invalid value for \"int32\", must be greater than or equal to 20.") end - if @number > 543.2 + if @number.try &.> 543.2 invalid_properties.push("invalid value for \"number\", must be smaller than or equal to 543.2.") end - if @number < 32.1 + if @number.try &.< 32.1 invalid_properties.push("invalid value for \"number\", must be greater than or equal to 32.1.") end - if !@float.nil? && @float > 987.6 + if !@float.nil? && @float.try &.> 987.6 invalid_properties.push("invalid value for \"float\", must be smaller than or equal to 987.6.") end - if !@float.nil? && @float < 54.3 + if !@float.nil? && @float.try &.< 54.3 invalid_properties.push("invalid value for \"float\", must be greater than or equal to 54.3.") end - if !@double.nil? && @double > 123.4 + if !@double.nil? && @double.try &.> 123.4 invalid_properties.push("invalid value for \"double\", must be smaller than or equal to 123.4.") end - if !@double.nil? && @double < 67.8 + if !@double.nil? && @double.try &.< 67.8 invalid_properties.push("invalid value for \"double\", must be greater than or equal to 67.8.") end - pattern = Regexp.new(/[a-z]/i) - if !@string.nil? && @string !~ pattern + pattern = /[a-z]/i + if !@string.nil? && @string.try &.!~ pattern invalid_properties.push("invalid value for \"string\", must conform to the pattern #{pattern}.") end - if @password.to_s.size > 64 + if @password.try &.to_s.try &.size.try &.> 64 invalid_properties.push("invalid value for \"password\", the character length must be smaller than or equal to 64.") end - if @password.to_s.size < 10 + if @password.try &.to_s.try &.size.try &.< 10 invalid_properties.push("invalid value for \"password\", the character length must be greater than or equal to 10.") end - pattern = Regexp.new(/^\d{10}$/) - if !@pattern_with_digits.nil? && @pattern_with_digits !~ pattern + pattern = /^\d{10}$/ + if !@pattern_with_digits.nil? && @pattern_with_digits.try &.!~ pattern invalid_properties.push("invalid value for \"pattern_with_digits\", must conform to the pattern #{pattern}.") end - pattern = Regexp.new(/^image_\d{1,3}$/i) - if !@pattern_with_digits_and_delimiter.nil? && @pattern_with_digits_and_delimiter !~ pattern + pattern = /^image_\d{1,3}$/i + if !@pattern_with_digits_and_delimiter.nil? && @pattern_with_digits_and_delimiter.try &.!~ pattern invalid_properties.push("invalid value for \"pattern_with_digits_and_delimiter\", must conform to the pattern #{pattern}.") end @@ -148,21 +148,21 @@ module Petstore # Check to see if the all the properties in the model are valid # @return true if the model is valid def valid? - return false if !@integer.nil? && @integer > 100 - return false if !@integer.nil? && @integer < 10 - return false if !@int32.nil? && @int32 > 200 - return false if !@int32.nil? && @int32 < 20 - return false if @number > 543.2 - return false if @number < 32.1 - return false if !@float.nil? && @float > 987.6 - return false if !@float.nil? && @float < 54.3 - return false if !@double.nil? && @double > 123.4 - return false if !@double.nil? && @double < 67.8 - return false if !@string.nil? && @string !~ Regexp.new(/[a-z]/i) - return false if @password.to_s.size > 64 - return false if @password.to_s.size < 10 - return false if !@pattern_with_digits.nil? && @pattern_with_digits !~ Regexp.new(/^\d{10}$/) - return false if !@pattern_with_digits_and_delimiter.nil? && @pattern_with_digits_and_delimiter !~ Regexp.new(/^image_\d{1,3}$/i) + return false if !@integer.nil? && @integer.try &.> 100 + return false if !@integer.nil? && @integer.try &.< 10 + return false if !@int32.nil? && @int32.try &.> 200 + return false if !@int32.nil? && @int32.try &.< 20 + return false if @number.try &.> 543.2 + return false if @number.try &.< 32.1 + return false if !@float.nil? && @float.try &.> 987.6 + return false if !@float.nil? && @float.try &.< 54.3 + return false if !@double.nil? && @double.try &.> 123.4 + return false if !@double.nil? && @double.try &.< 67.8 + return false if !@string.nil? && @string.try &.!~ /[a-z]/i + return false if @password.try &.to_s.try &.size.try &.> 64 + return false if @password.try &.to_s.try &.size.try &.< 10 + return false if !@pattern_with_digits.nil? && @pattern_with_digits.try &.!~ /^\d{10}$/ + return false if !@pattern_with_digits_and_delimiter.nil? && @pattern_with_digits_and_delimiter.try &.!~ /^image_\d{1,3}$/i true end @@ -239,7 +239,7 @@ module Petstore # Custom attribute writer method with validation # @param [Object] string Value to be assigned def string=(string) - pattern = Regexp.new(/[a-z]/i) + pattern = /[a-z]/i if !string.nil? && string !~ pattern raise ArgumentError.new("invalid value for \"string\", must conform to the pattern #{pattern}.") end @@ -264,7 +264,7 @@ module Petstore # Custom attribute writer method with validation # @param [Object] pattern_with_digits Value to be assigned def pattern_with_digits=(pattern_with_digits) - pattern = Regexp.new(/^\d{10}$/) + pattern = /^\d{10}$/ if !pattern_with_digits.nil? && pattern_with_digits !~ pattern raise ArgumentError.new("invalid value for \"pattern_with_digits\", must conform to the pattern #{pattern}.") end @@ -275,7 +275,7 @@ module Petstore # Custom attribute writer method with validation # @param [Object] pattern_with_digits_and_delimiter Value to be assigned def pattern_with_digits_and_delimiter=(pattern_with_digits_and_delimiter) - pattern = Regexp.new(/^image_\d{1,3}$/i) + pattern = /^image_\d{1,3}$/i if !pattern_with_digits_and_delimiter.nil? && pattern_with_digits_and_delimiter !~ pattern raise ArgumentError.new("invalid value for \"pattern_with_digits_and_delimiter\", must conform to the pattern #{pattern}.") end @@ -393,44 +393,51 @@ module Petstore # 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 = {} of Symbol => String - 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 + hash["integer"] = _to_h(integer) + hash["int32"] = _to_h(int32) + hash["int64"] = _to_h(int64) + hash["number"] = _to_h(number) + hash["float"] = _to_h(float) + hash["double"] = _to_h(double) + hash["decimal"] = _to_h(decimal) + hash["string"] = _to_h(string) + hash["byte"] = _to_h(byte) + hash["binary"] = _to_h(binary) + hash["date"] = _to_h(date) + hash["dateTime"] = _to_h(date_time) + hash["uuid"] = _to_h(uuid) + hash["password"] = _to_h(password) + hash["pattern_with_digits"] = _to_h(pattern_with_digits) + hash["pattern_with_digits_and_delimiter"] = _to_h(pattern_with_digits_and_delimiter) + 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 diff --git a/samples/client/petstore/crystal/src/petstore/models/order.cr b/samples/client/petstore/crystal/src/petstore/models/order.cr index 67b150697cb2..b1a33f580fe7 100644 --- a/samples/client/petstore/crystal/src/petstore/models/order.cr +++ b/samples/client/petstore/crystal/src/petstore/models/order.cr @@ -39,45 +39,64 @@ module Petstore @[JSON::Field(key: "complete", type: Bool?, default: false, nillable: true, emit_null: false)] property complete : Bool? - 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) + class EnumAttributeValidatorForStatus < EnumAttributeValidator + @attribute : String + @allowable_values : Array(Int32 | Int64 | Float32 | Float64 | String) + + def initialize + @attribute = "status" + @allowable_values = ["placed", "approved", "delivered"].map { |value| to(String, value)} end end + # Initializes the object # @param [Hash] attributes Model attributes in the form of hash - def initialize(@id : Int64?, @pet_id : Int64?, @quantity : Int32?, @ship_date : Time?, @status : String?, @complete : Bool?) + def initialize(@id : Int64? = nil, @pet_id : Int64? = nil, @quantity : Int32? = nil, @ship_date : Time? = nil, @status : String? = nil, @complete : Bool? = nil) 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 = Array(String).new + status_validator = EnumAttributeValidatorForStatus.new + if !status_validator.valid?(@status) + message = status_validator.message + invalid_properties.push(message) + end + invalid_properties end # Check to see if the all the properties in the model are valid # @return true if the model is valid def valid? - status_validator = EnumAttributeValidator.new("String", ["placed", "approved", "delivered"]) + status_validator = EnumAttributeValidatorForStatus.new return false unless status_validator.valid?(@status) true end @@ -85,9 +104,9 @@ module Petstore # Custom attribute writer method checking allowed values (enum). # @param [Object] status Object to be assigned def status=(status) - validator = EnumAttributeValidator.new("String", ["placed", "approved", "delivered"]) + validator = EnumAttributeValidatorForStatus.new unless validator.valid?(status) - raise ArgumentError.new("invalid value for \"status\", must be one of #{validator.allowable_values}.") + raise ArgumentError.new(validator.message) end @status = status end @@ -192,44 +211,41 @@ module Petstore # 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 = {} of Symbol => String - 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 + hash["id"] = _to_h(id) + hash["petId"] = _to_h(pet_id) + hash["quantity"] = _to_h(quantity) + hash["shipDate"] = _to_h(ship_date) + hash["status"] = _to_h(status) + hash["complete"] = _to_h(complete) + 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 diff --git a/samples/client/petstore/crystal/src/petstore/models/pet.cr b/samples/client/petstore/crystal/src/petstore/models/pet.cr index 21a7a9a437f0..21d46467521c 100644 --- a/samples/client/petstore/crystal/src/petstore/models/pet.cr +++ b/samples/client/petstore/crystal/src/petstore/models/pet.cr @@ -40,45 +40,64 @@ module Petstore @[JSON::Field(key: "status", type: String?, nillable: true, emit_null: false)] property status : String? - 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) + class EnumAttributeValidatorForStatus < EnumAttributeValidator + @attribute : String + @allowable_values : Array(Int32 | Int64 | Float32 | Float64 | String) + + def initialize + @attribute = "status" + @allowable_values = ["available", "pending", "sold"].map { |value| to(String, value)} end end + # Initializes the object # @param [Hash] attributes Model attributes in the form of hash - def initialize(@name : String, @photo_urls : Array(String), @id : Int64?, @category : Category?, @tags : Array(Tag)?, @status : String?) + def initialize(@name : String, @photo_urls : Array(String), @id : Int64? = nil, @category : Category? = nil, @tags : Array(Tag)? = nil, @status : String? = nil) 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 = Array(String).new + status_validator = EnumAttributeValidatorForStatus.new + if !status_validator.valid?(@status) + message = status_validator.message + invalid_properties.push(message) + end + invalid_properties end # Check to see if the all the properties in the model are valid # @return true if the model is valid def valid? - status_validator = EnumAttributeValidator.new("String", ["available", "pending", "sold"]) + status_validator = EnumAttributeValidatorForStatus.new return false unless status_validator.valid?(@status) true end @@ -86,9 +105,9 @@ module Petstore # Custom attribute writer method checking allowed values (enum). # @param [Object] status Object to be assigned def status=(status) - validator = EnumAttributeValidator.new("String", ["available", "pending", "sold"]) + validator = EnumAttributeValidatorForStatus.new unless validator.valid?(status) - raise ArgumentError.new("invalid value for \"status\", must be one of #{validator.allowable_values}.") + raise ArgumentError.new(validator.message) end @status = status end @@ -193,44 +212,41 @@ module Petstore # 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 = {} of Symbol => String - 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 + hash["id"] = _to_h(id) + hash["category"] = _to_h(category) + hash["name"] = _to_h(name) + hash["photoUrls"] = _to_h(photo_urls) + hash["tags"] = _to_h(tags) + hash["status"] = _to_h(status) + 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 diff --git a/samples/client/petstore/crystal/src/petstore/models/tag.cr b/samples/client/petstore/crystal/src/petstore/models/tag.cr index 71b52cf1f056..ca8877e3b43d 100644 --- a/samples/client/petstore/crystal/src/petstore/models/tag.cr +++ b/samples/client/petstore/crystal/src/petstore/models/tag.cr @@ -28,7 +28,7 @@ module Petstore # Initializes the object # @param [Hash] attributes Model attributes in the form of hash - def initialize(@id : Int64?, @name : String?) + def initialize(@id : Int64? = nil, @name : String? = nil) end # Show invalid properties with the reasons. Usually used together with valid? @@ -140,44 +140,37 @@ module Petstore # 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 = {} of Symbol => String - 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 + hash["id"] = _to_h(id) + hash["name"] = _to_h(name) + 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 diff --git a/samples/client/petstore/crystal/src/petstore/models/user.cr b/samples/client/petstore/crystal/src/petstore/models/user.cr index 7394330674e3..6b284af5e0f4 100644 --- a/samples/client/petstore/crystal/src/petstore/models/user.cr +++ b/samples/client/petstore/crystal/src/petstore/models/user.cr @@ -47,7 +47,7 @@ module Petstore # Initializes the object # @param [Hash] attributes Model attributes in the form of hash - def initialize(@id : Int64?, @username : String?, @first_name : String?, @last_name : String?, @email : String?, @password : String?, @phone : String?, @user_status : Int32?) + def initialize(@id : Int64? = nil, @username : String? = nil, @first_name : String? = nil, @last_name : String? = nil, @email : String? = nil, @password : String? = nil, @phone : String? = nil, @user_status : Int32? = nil) end # Show invalid properties with the reasons. Usually used together with valid? @@ -165,44 +165,43 @@ module Petstore # 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 = {} of Symbol => String - 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 + hash["id"] = _to_h(id) + hash["username"] = _to_h(username) + hash["firstName"] = _to_h(first_name) + hash["lastName"] = _to_h(last_name) + hash["email"] = _to_h(email) + hash["password"] = _to_h(password) + hash["phone"] = _to_h(phone) + hash["userStatus"] = _to_h(user_status) + 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 diff --git a/samples/client/petstore/crystal/src/petstore/recursive_hash.cr b/samples/client/petstore/crystal/src/petstore/recursive_hash.cr new file mode 100644 index 000000000000..cd3435abf801 --- /dev/null +++ b/samples/client/petstore/crystal/src/petstore/recursive_hash.cr @@ -0,0 +1,18 @@ +module Petstore + # 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