<commit_before>require 'active_support'

require_relative '../exceptions'

module Attributor
  class Polymorphic
    include Type

    class << self
      attr_reader :discriminator
      attr_reader :types
    end

    def self.on(discriminator)
      ::Class.new(self) do
        @discriminator = discriminator
      end
    end

    def self.given(value, type)
      @types[value] = type
    end

    def self.inherited(klass)
      klass.instance_eval do
        @types = {}
      end
    end

    def self.example(context = nil, **values)
      types.values.pick.example(context, **values)
    end

    def self.valid_type?(value)
      self.types.values.include?(value.class)
    end

    def self.constructable?
      true
    end

    def self.native_type
      self
    end

    def self.construct(block, **_options)
      self.instance_eval(&block)
      self
    end

    def self.load(value, context = Attributor::DEFAULT_ROOT_CONTEXT, **_options)
      return nil if value.nil?

      return value if self.types.values.include?(value.class)

      loaded_value = self.parse(value, context)

      discriminator = loaded_value.fetch(self.discriminator)

      type = self.types.fetch(loaded_value[self.discriminator]) do
        raise "invalid value for discriminator: #{discriminator}"
      end
      type.load(loaded_value)
    end

    def self.parse(value, context)
      if value.nil?
        {}
      elsif value.is_a?(Attributor::Hash)
        value.contents
      elsif value.is_a?(::Hash)
        value<commit_msg>Fix Polymorphic.construct<commit_after>require 'active_support'

require_relative '../exceptions'

module Attributor
  class Polymorphic
    include Type

    class << self
      attr_reader :discriminator
      attr_reader :types
    end

    def self.on(discriminator)
      ::Class.new(self) do
        @discriminator = discriminator
      end
    end

    def self.given(value, type)
      @types[value] = type
    end

    def self.inherited(klass)
      klass.instance_eval do
        @types = {}
      end
    end

    def self.example(context = nil, **values)
      types.values.pick.example(context, **values)
    end

    def self.valid_type?(value)
      self.types.values.include?(value.class)
    end

    def self.constructable?
      true
    end

    def self.native_type
      self
    end

    def self.construct(constructor_block, **_options)
      return self if constructor_block.nil?

      self.instance_eval(&constructor_block)
      self
    end

    def self.load(value, context = Attributor::DEFAULT_ROOT_CONTEXT, **_options)
      return nil if value.nil?

      return value if self.types.values.include?(value.class)

      loaded_value = self.parse(value, context)

      discriminator = loaded_value.fetch(self.discriminator)

      type = self.types.fetch(loaded_value[self.discriminator]) do
        raise "invalid value for discriminator: #{discriminator}"
      end
      type.load(loaded_value)
    end

    def self.parse(value, context)
      if value.nil?
        {}
      elsif value.is_a?(Attributor::Hash)
        value.contents
      elsif value.is_a?(::Hash)
        value
{'fraction_non_alphanumeric': 0.0935616872819537, 'fraction_numerical': 0.0, 'mean_word_length': 2.4773980154355018, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, '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': '6797017', 'n_tokens_mistral': 975, 'n_tokens_neox': 950, 'n_words': 212}