<commit_before>require 'argo/string_property'
require 'argo/integer_property'
require 'argo/number_property'
require 'argo/array_property'

module Argo
  class PropertyFactory
    NON_CONSTRAINT_PROPERTIES = %w[
      description
      items
      type
    ]

    TYPE_MAP = {
      'string' => StringProperty,
      'integer' => IntegerProperty,
      'number' => NumberProperty,
      'array' => ArrayProperty
    }

    def initialize(required_fields = [])
      @required_fields = required_fields
    end

    def build(name, body)
      class_for_type(body).new(
        constraints: constraints(body),
        description: body['description'],
        name: name,
        required: required?(name),
        **additional_properties(body)
      )
    rescue => e
      raise e, e.message + ' in ' + body.inspect
    end

  private

    def class_for_type(body)
      implicit_class(body) || explicit_class(body)
    end

    def explicit_class(body)
      TYPE_MAP.fetch(body['type'])
    end

    def implicit_class(body)
      body.key?('enum') && StringProperty
    end

    def additional_properties(body)
      if class_for_type(body) == ArrayProperty
        additional_properties_for_array(body)
      else
        {}
      end
    end<commit_msg>Make unknown type error more helpful<commit_after>require 'argo/string_property'
require 'argo/integer_property'
require 'argo/number_property'
require 'argo/array_property'

module Argo
  class PropertyFactory
    NON_CONSTRAINT_PROPERTIES = %w[
      description
      items
      type
    ]

    TYPE_MAP = {
      'string' => StringProperty,
      'integer' => IntegerProperty,
      'number' => NumberProperty,
      'array' => ArrayProperty
    }

    def initialize(required_fields = [])
      @required_fields = required_fields
    end

    def build(name, body)
      class_for_type(body).new(
        constraints: constraints(body),
        description: body['description'],
        name: name,
        required: required?(name),
        **additional_properties(body)
      )
    rescue => e
      raise e, e.message + ' in ' + body.inspect
    end

  private

    def class_for_type(body)
      implicit_class(body) || explicit_class(body)
    end

    def explicit_class(body)
      type = body['type']
      raise "Unknown property type '#{type}'" unless TYPE_MAP.key?(type)
      TYPE_MAP.fetch(type)
    end

    def implicit_class(body)
      body.key?('enum') && StringProperty
    end

    def additional_properties(body)
      if class_for_type(body) == ArrayProperty
        additional_properties_for_array(body)
      else
        {}
      end
    end
{'fraction_non_alphanumeric': 0.09809885931558936, 'fraction_numerical': 0.0, 'mean_word_length': 2.659248956884562, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2240114', 'n_tokens_mistral': 783, 'n_tokens_neox': 771, 'n_words': 165}