| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- require 'yajl/json_gem'
- module Docs
- class EntryIndex
- attr_reader :entries, :types
- def initialize
- @entries = []
- @index = Set.new
- @types = Hash.new { |hash, key| hash[key] = Type.new key }
- end
- def add(entry)
- if entry.is_a? Array
- entry.each(&method(:add))
- else
- add_entry(entry) unless entry.root?
- end
- end
- def empty?
- @entries.empty?
- end
- alias_method :blank?, :empty?
- def length
- @entries.length
- end
- def as_json
- { entries: entries_as_json, types: types_as_json }
- end
- def to_json
- JSON.generate(as_json)
- end
- private
- def add_entry(entry)
- if @index.add?(entry.as_json.to_s)
- @entries << entry.dup
- @types[entry.type].count += 1 if entry.type
- end
- end
- def entries_as_json
- @entries.sort! { |a, b| sort_fn(a.name, b.name) }.map(&:as_json)
- end
- def types_as_json
- @types.values.sort! { |a, b| sort_fn(a.name, b.name) }.map(&:as_json)
- end
- SPLIT_INTS = /(?<=\d)\.(?=[\s\d])/.freeze
- def sort_fn(a, b)
- if (a.getbyte(0) >= 49 && a.getbyte(0) <= 57) || (b.getbyte(0) >= 49 && b.getbyte(0) <= 57)
- a_split = a.split(SPLIT_INTS)
- b_split = b.split(SPLIT_INTS)
- a_length = a_split.length
- b_length = b_split.length
- return a.casecmp(b) if a_length == 1 && b_length == 1
- return 1 if a_length == 1
- return -1 if b_length == 1
- a_split.each_with_index { |s, i| a_split[i] = s.to_i unless i == a_length - 1 }
- b_split.each_with_index { |s, i| b_split[i] = s.to_i unless i == b_length - 1 }
- if b_length > a_length
- (b_length - a_length).times { a_split.insert(-2, 0) }
- elsif a_length > b_length
- (a_length - b_length).times { b_split.insert(-2, 0) }
- end
- a_split <=> b_split
- else
- a.casecmp(b)
- end
- end
- end
- end
|