module {{ name }} class << self include BaseOneOfModel {%- if not model.discriminator %} include BaseOneOfModelNoDiscriminator {%- endif %} # List of class defined in oneOf (OpenAPI v3) def openapi_one_of [ {%- for schema in model.oneOf %} :'{{ type_to_ruby(schema) }}'{% if not loop.last %},{% endif %} {%- endfor %} ] end {%- if model.discriminator %} {%- if model.discriminator.propertyName %} # Discriminator's property name (OpenAPI v3) def openapi_discriminator_name :'{{ model.discriminator.propertyName}}' end {%- endif %} {# TODO add support for discriminator mapping (OpenAPI v3) {{#mappedModels}} {{#-first}} # Discriminator's mapping (OpenAPI v3) def openapi_discriminator_mapping { {{/-first}} :'{{{mappingName}}}' => :'{{{modelName}}}'{{^-last}},{{/-last}} {{#-last}} } end {{/-last}} {{/mappedModels}} #} {%- endif %} # Builds the object # @param [Mixed] Data to be matched against the list of oneOf items # @return [Object] Returns the model or the data itself def build(data) {%- if model.discriminator %} discriminator_value = data[openapi_discriminator_name] return nil unless discriminator_value {# TODO {{#mappedModels}} {{#-first}} klass = openapi_discriminator_mapping[discriminator_value.to_sym] return nil unless klass {{ module_name }}::{{ version|upper }}.const_get(klass).build_from_hash(data) {{/-first}} {{/mappedModels}} {{^mappedModels}} {{ module_name }}::{{ version|upper }}.const_get(discriminator_value).build_from_hash(data) {{/mappedModels}} #} {%- else %} # Go through the list of oneOf items and attempt to identify the appropriate one. # Note: # - We do not attempt to check whether exactly one item matches. # - No advanced validation of types in some cases (e.g. "x: { type: string }" will happily match { x: 123 }) # due to the way the deserialization is made in the base_object template (it just casts without verifying). # - TODO: scalar values are de facto behaving as if they were nullable. # - TODO: logging when debugging is set. openapi_one_of.each do |klass| begin next if klass == :AnyType # "nullable: true" typed_data = find_and_cast_into_type(klass, data) next if typed_data._unparsed return typed_data if typed_data rescue # rescue all errors so we keep iterating even if the current item lookup raises end end if openapi_one_of.include?(:AnyType) data else self._unparsed = true {{ module_name }}::UnparsedObject.new(data) end {%- endif %} end end end