travis-api/lib/travis/api/v3/paginator/url_generator.rb
2015-08-21 17:04:12 +02:00

96 lines
2.2 KiB
Ruby

require "addressable/uri"
module Travis::API::V3
class Paginator
class URLGenerator
class FancyParser
def initialize(href)
@uri = Addressable::URI.parse(href)
end
def generate(offset, limit)
uri = @uri.dup
uri.query_values = uri.query_values.merge("offset".freeze => offset, "limit".freeze => limit)
uri.to_s
end
end
class FastParser
PATTERN = /\?(?:&?(?:limit|offset)=[^=]*)*\Z/
def self.can_handle?(href)
return true unless href.include? ??.freeze
href =~ PATTERN
end
def initialize(href)
@path_info = href.split(??.freeze, 2).first
end
def generate(offset, limit)
"#{@path_info}?limit=#{limit}&offset=#{offset}"
end
end
def initialize(href, limit: 0, offset: 0, count: 0, **)
@parser = FastParser.can_handle?(href) ? FastParser.new(href) : FancyParser.new(href)
@href = href
@limit = limit
@offset = offset
@count = count
end
def last?
@count <= @offset + @limit
end
def first?
@offset == 0
end
def next_info
info(offset: @offset + @limit) unless last?
end
def previous_info
return if @offset == 0
@offset <= @limit ? info(offset: 0, limit: @offset) : info(offset: @offset - @limit, limit: @limit)
end
def first_info
info(offset: 0)
end
def last_info
offset = @count / @limit * @limit
offset -= @limit if offset == @count
info(offset: offset)
end
def info(offset: @offset, limit: @limit)
{
:@href => uri_with(offset, limit),
:offset => offset,
:limit => limit
}
end
def to_h
{
is_first: first?,
is_last: last?,
next: next_info,
prev: previous_info,
first: first_info,
last: last_info
}
end
def uri_with(offset, limit)
return @href if offset == @offset and limit == @limit
@parser.generate(offset, limit)
end
end
end
end