Class: Candid::Internal::OffsetPageIterator

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/candid/internal/iterators/offset_page_iterator.rb

Instance Method Summary collapse

Constructor Details

#initialize(initial_page:, item_field:, has_next_field:, step:, &block) ⇒ Candid::Internal::OffsetPageIterator

Instantiates an OffsetPageIterator, an Enumerable class which wraps calls to an offset-based paginated API and yields pages of items from it.

Parameters:

  • initial_page (Integer)

    The initial page to use when iterating, if any.

  • item_field (Symbol)

    The field to pull the list of items to iterate over.

  • has_next_field (Symbol)

    The field to pull the boolean of whether a next page exists from, if any.

  • step (Boolean)

    If true, treats the page number as a true offset (i.e. increments the page number by the number of items returned from each call rather than just 1)

  • block (Proc)

    A block which is responsible for receiving a page number to use and returning the given page from the API.



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/candid/internal/iterators/offset_page_iterator.rb', line 16

def initialize(initial_page:, item_field:, has_next_field:, step:, &block)
  @page_number = initial_page || (step ? 0 : 1)
  @item_field = item_field
  @has_next_field = has_next_field
  @step = step
  @get_next_page = block

  # A cache of whether the API has another page, if it gives us that information...
  @next_page = nil
  # ...or the actual next page, preloaded, if it doesn't.
  @has_next_page = nil
end

Instance Method Details

#each(&block) ⇒ NilClass

Iterates over each page returned by the API.

Parameters:

  • block (Proc)

    The block which each retrieved page is yielded to.

Returns:

  • (NilClass)


33
34
35
36
37
# File 'lib/candid/internal/iterators/offset_page_iterator.rb', line 33

def each(&block)
  while (page = get_next)
    block.call(page)
  end
end

#get_nextObject

Returns the next page from the API.



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/candid/internal/iterators/offset_page_iterator.rb', line 57

def get_next
  return nil if @page_number.nil?

  if @next_page
    this_page = @next_page
    @next_page = nil
  else
    this_page = @get_next_page.call(@page_number)
  end

  @has_next_page = this_page&.send(@has_next_field) if @has_next_field

  items = this_page.send(@item_field)
  if items.nil? || items.empty?
    @page_number = nil
    return nil
  elsif @step
    @page_number += items.length
  else
    @page_number += 1
  end

  this_page
end

#has_next?Boolean

Whether another page will be available from the API.

Returns:

  • (Boolean)


42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/candid/internal/iterators/offset_page_iterator.rb', line 42

def has_next?
  return @has_next_page unless @has_next_page.nil?
  return true if @next_page

  next_page = @get_next_page.call(@page_number)
  next_page_items = next_page&.send(@item_field)
  if next_page_items.nil? || next_page_items.empty?
    @has_next_page = false
  else
    @next_page = next_page
    true
  end
end