File: paginated_collection.rb

package info (click to toggle)
ruby-puppet-forge 5.0.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,196 kB
  • sloc: ruby: 2,397; makefile: 3
file content (82 lines) | stat: -rw-r--r-- 2,788 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
module PuppetForge
  module V3
    class Base

      # Enables navigation of the Forge API's paginated datasets.
      class PaginatedCollection < Array

        # Default pagination limit for API request
        LIMIT = 20

        # @api private
        # @param klass [PuppetForge::V3::Base] the class to page over
        # @param data [Array] the current data page
        # @param metadata [Hash<(:limit, :total, :offset)>] page metadata
        # @param errors [Object] errors for the page request
        def initialize(klass, data = [], metadata = {:total => 0, :offset => 0, :limit => LIMIT}, errors = nil)
          super()
          @metadata = metadata
          @errors = errors
          @klass = klass

          data.each do |item|
            self << @klass.new(item)
          end
        end

        # For backwards compatibility, all returns the current object.
        def all
          self
        end

        # An enumerator that iterates over the entire collection, independent
        # of API pagination. This will potentially result in several API
        # requests.
        #
        # @return [Enumerator] an iterator for the entire collection
        def unpaginated
          page = @klass.get_collection(@metadata[:first])
          Enumerator.new do |emitter|
            loop do
              page.each { |x| emitter << x }
              break unless page = page.next
            end
          end
        end

        # @!method total
        #   @return [Integer] the size of the unpaginated dataset
        # @!method limit
        #   @return [Integer] the maximum size of any page in this dataset
        # @!method offset
        #   @return [Integer] the offset for the current page
        [ :total, :limit, :offset ].each do |info|
          define_method(info) { @metadata[info] }
        end

        [ :next, :previous ].each do |link|
          # @!method next
          #   Returns the next page if a next page exists.
          #   @return [PaginatedCollection, nil] the next page
          # @!method previous
          #   Returns the previous page if a previous page exists.
          #   @return [PaginatedCollection, nil] the previous page
          define_method(link) do
            return unless path = @metadata[link]
            @klass.get_collection(path)
          end

          # @!method next_url
          #   Returns the url of the next page if a next page exists.
          #   @return [String, nil] the next page's url
          # @!method previous_url
          #   Returns the url of the previous page if a previous page exists.
          #   @return [String, nil] the previous page's url
          define_method("#{link}_url") do
            @metadata[link]
          end
        end
      end
    end
  end
end