<commit_before>class TypeStruct
  require "type_struct/union"
  require "type_struct/arrayof"
  require "type_struct/interface"
  require "type_struct/version"

  def initialize(arg)
    sym_arg = {}
    arg.each do |k, v|
      sym_arg[k.to_sym] = v
    end
    self.class.members.each do |k|
      self[k] = sym_arg[k]
    end
  end

  def ==(other)
    return false unless TypeStruct === other
    return false unless to_h == other.to_h
    true
  end

  def []=(k, v)
    __send__("#{k}=", v)
  end

  def [](k)
    __send__(k)
  end

  def inspect
    m = to_h.map do |k, v|
      "#{k}=#{v.inspect}"
    end
    "#<#{self.class} #{m.join(', ')}>"
  end

  def to_h
    m = {}
    self.class.members.each do |k|
      m[k] = self[k]
    end
    m
  end

  class << self
    def try_convert(klass, value)
      return nil unless klass

      if Union === klass
        klass.each do |k|
          t = try_convert(k, value)
          return t if !t.nil?
        end
        nil
      elsif ArrayOf === klass
        value.map { |v| try_convert(klass.type, v) }
      elsif klass.ancestors.include?(TypeStruct)
        klass.from_hash(value)
      elsif klass.ancestors.include?(Struct)
        struct = klass.new
        value.each { |k, v| struct[k] = v }
        struct
      else
        value
      end
    rescue
      nil
    end

    def from_hash(h)
      args = {}
      h.each do |key, value|
        key = key.to_sym
        t = type(key)
        if Class === t
          case
          when t.ancestors.include?(TypeStruct)
            args[key] = t.from_hash(value)
          when t.ancestors.include?(Struct)
            struct = t.new
            value.each { |k, v| struct[k] = v }
            args[key] = struct
          when t.respond_to?(:new)
            args[key] = t.new(value)
          else
            args[key] = value
          end
        elsif ArrayOf === t
          args[key] = if value.respond_to?(:map)
            value.map { |v| try_convert(t.type, v) }
          else
            value
          end
        else
          args[key] = try_convert(t, value)
        end
      end
      new(args)
    end

    def definition
      const_get(:DEFINITION)
    end

    def members
      definition.keys
    end

    def type(k)
      definition[k]
    end
<commit_msg>Refactoring<commit_after>class TypeStruct
  require "type_struct/union"
  require "type_struct/arrayof"
  require "type_struct/interface"
  require "type_struct/version"

  def initialize(arg)
    sym_arg = {}
    arg.each do |k, v|
      sym_arg[k.to_sym] = v
    end
    self.class.members.each do |k|
      self[k] = sym_arg[k]
    end
  end

  def ==(other)
    return false unless TypeStruct === other
    return false unless to_h == other.to_h
    true
  end

  def []=(k, v)
    __send__("#{k}=", v)
  end

  def [](k)
    __send__(k)
  end

  def inspect
    m = to_h.map do |k, v|
      "#{k}=#{v.inspect}"
    end
    "#<#{self.class} #{m.join(', ')}>"
  end

  def to_h
    m = {}
    self.class.members.each do |k|
      m[k] = self[k]
    end
    m
  end

  class << self
    def try_convert(klass, value)
      return nil unless klass

      if Union === klass
        klass.each do |k|
          t = try_convert(k, value)
          return t if !t.nil?
        end
        nil
      elsif ArrayOf === klass
        value.map { |v| try_convert(klass.type, v) }
      elsif klass.ancestors.include?(TypeStruct)
        klass.from_hash(value)
      elsif klass.ancestors.include?(Struct)
        struct = klass.new
        value.each { |k, v| struct[k] = v }
        struct
      else
        value
      end
    rescue
      nil
    end

    def from_hash(h)
      args = {}
      h.each do |key, value|
        key = key.to_sym
        t = type(key)
        args[key] = try_convert(t, value)
      end
      new(args)
    end

    def definition
      const_get(:DEFINITION)
    end

    def members
      definition.keys
    end

    def type(k)
      definition[k]
    end

{'fraction_non_alphanumeric': 0.11648296593186373, 'fraction_numerical': 0.0, 'mean_word_length': 1.690700808625337, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, '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': '306123', 'n_tokens_mistral': 1400, 'n_tokens_neox': 1411, 'n_words': 348}