<commit_before>require 'active_support'
require 'ostruct'
require 'xmlsimple'

class LiveSplitParser
  def parse(xml)
    xml = XmlSimple.xml_in(xml)
    version = Versionomy.parse(xml['version'] || '1.2')
    run = OpenStruct.new
    return v1_3(run, xml) if version >= Versionomy.parse('1.3')
    return v1_2(run, xml) if version >= Versionomy.parse('1.2')
    return nil
  rescue REXML::ParseException
    nil
  end

  private

  # LiveSplit version parsing waterfalls down to the lowest version possible. For instance, 1.3 and 1.2 parse almost
  # identically except for a minor difference in positioning of split times. So the 1.3 function parses only splits,
  # then hands the rest of the XML off to the 1.2 function, which parses the rest as if it were 1.2 content.

  def v1_3(run, xml)
    run.splits ||= []
    run.time   ||= 0
    xml['Segments'].first.first.second.each do |segment|
      split = OpenStruct.new
      split.best = OpenStruct.new
      split.name = segment['Name'].first

      # Okay what the hell. There's no way XML parsing is this crazy.
      # Somebody please enlighten me. Maybe I should switch this to Nokogiri.
      split.finish_time = duration_in_seconds_of(segment['SplitTimes'].first.first.second
                                                .select { |k, _| k['name'] == 'Personal Best' }.first['content'].strip)
      split.duration = split.finish_time - run.time
      split.duration = 0 if split.duration < 0<commit_msg>Correctly show "cant parse that" on failed parses<commit_after>require 'active_support'
require 'ostruct'
require 'xmlsimple'

class LiveSplitParser
  def parse(xml)
    xml = XmlSimple.xml_in(xml)
    version = Versionomy.parse(xml['version'] || '1.2')
    run = OpenStruct.new
    return v1_3(run, xml) if version >= Versionomy.parse('1.3')
    return v1_2(run, xml) if version >= Versionomy.parse('1.2')
    return nil
  rescue
    nil
  end

  private

  # LiveSplit version parsing waterfalls down to the lowest version possible. For instance, 1.3 and 1.2 parse almost
  # identically except for a minor difference in positioning of split times. So the 1.3 function parses only splits,
  # then hands the rest of the XML off to the 1.2 function, which parses the rest as if it were 1.2 content.

  def v1_3(run, xml)
    run.splits ||= []
    run.time   ||= 0
    xml['Segments'].first.first.second.each do |segment|
      split = OpenStruct.new
      split.best = OpenStruct.new
      split.name = segment['Name'].first

      # Okay what the hell. There's no way XML parsing is this crazy.
      # Somebody please enlighten me. Maybe I should switch this to Nokogiri.
      split.finish_time = duration_in_seconds_of(segment['SplitTimes'].first.first.second
                                                .select { |k, _| k['name'] == 'Personal Best' }.first['content'].strip)
      split.duration = split.finish_time - run.time
      split.duration = 0 if split.duration < 0
{'fraction_non_alphanumeric': 0.1016260162601626, 'fraction_numerical': 0.016937669376693765, 'mean_word_length': 2.9112582781456955, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 20}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5865125', 'n_tokens_mistral': 912, 'n_tokens_neox': 870, 'n_words': 299}