96 lines
2.2 KiB
Ruby
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
|