<commit_before># frozen_string_literal: true

require 'contracts'
require 'github_api'
require 'how_is/pulse'

##
# Fetches data from GitHub.
class HowIs::Fetcher
  include Contracts::Core

  ##
  # Standardized representation for fetcher results.
  #
  # Implemented as a class instead of passing around a Hash so that it can
  # be more easily referenced by Contracts.
  class Results < Struct.new(:repository, :issues, :pulls, :pulse)
    include Contracts::Core

    Contract String, C::ArrayOf[Hash], C::ArrayOf[Hash], String => nil
    def initialize(repository, issues, pulls, pulse)
      super(repository, issues, pulls, pulse)
    end

    # Struct defines #to_h, but not #to_hash, so we alias them.
    alias_method :to_hash, :to_h
  end


  ##
  # Fetches repository information from GitHub and returns a Results object.
  Contract String,
    C::Or[C::RespondTo[:issues, :pulls], nil],
    C::Or[C::RespondTo[:html_summary], nil] => Results
  def call(repository,
        github = nil,
        pulse = nil)
    github ||= Github.new(auto_pagination: true)
    pulse ||= HowIs::Pulse.new(repository)
    user, repo = repository.split('/', 2)

    unless user && repo
      raise HowIs::CLI::OptionsError, 'To generate a report from GitHub, ' \
                                      'provide the repository ' \
                                      'username/project. Quitting!'
    end

    issues  = github.issues.list user: user, repo: repo
    pulls   = github.pulls.list  user: user, repo: repo

    summary = pulse.html_summary

    Results.new(
      repository,
      obj_to_array_of_hashes(issues),
      obj_to_array_of_hashes(pulls),
      summary
    )
  end

  private

  def obj_to_array_of_hashes(object)
    object.to_a.map(&:to_h)
  end
end<commit_msg>[how_is/fetcher] use nested class defintions instead of compact style.<commit_after># frozen_string_literal: true

require 'contracts'
require 'github_api'
require 'how_is/pulse'

##
# Fetches data from GitHub.
class HowIs
  class Fetcher
    include Contracts::Core

    ##
    # Standardized representation for fetcher results.
    #
    # Implemented as a class instead of passing around a Hash so that it can
    # be more easily referenced by Contracts.
    class Results < Struct.new(:repository, :issues, :pulls, :pulse)
      include Contracts::Core

      Contract String, C::ArrayOf[Hash], C::ArrayOf[Hash], String => nil
      def initialize(repository, issues, pulls, pulse)
        super(repository, issues, pulls, pulse)
      end

      # Struct defines #to_h, but not #to_hash, so we alias them.
      alias_method :to_hash, :to_h
    end


    ##
    # Fetches repository information from GitHub and returns a Results object.
    Contract String,
      C::Or[C::RespondTo[:issues, :pulls], nil],
      C::Or[C::RespondTo[:html_summary], nil] => Results
    def call(repository,
             github = nil,
             pulse = nil)
      github ||= Github.new(auto_pagination: true)
      pulse ||= HowIs::Pulse.new(repository)
      user, repo = repository.split('/', 2)

      unless user && repo
        raise HowIs::CLI::OptionsError, 'To generate a report from GitHub, ' \
          'provide the repository ' \
          'username/project. Quitting!'
      end

      issues  = github.issues.list user: user, repo: repo
      pulls   = github.pulls.list  user: user, repo: repo

      summary = pulse.html_summary

      Results.new(
        repository,
        obj_to_array_of_hashes(issues),
        obj_to_array_of_hashes(pulls),
        summary
      )
    end

    private

    def obj_to_array_of_hashes(object)
      object.to_a.map(&:to_h)
    end
  end
end
{'fraction_non_alphanumeric': 0.10092744135297327, 'fraction_numerical': 0.0005455537370430987, 'mean_word_length': 2.7804123711340205, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4187936', 'n_tokens_mistral': 1152, 'n_tokens_neox': 1101, 'n_words': 322}