class Pagy::Calendar::Unit
Base class for time units subclasses (Year, Quarter, Month, Week, Day)
:nodoc:
:nodoc:
def active_period
def active_period [[@starting, @from].max, [@to - 1, @ending].min] # -1 sec: include only last unit day end
def assign_unit_vars
def assign_unit_vars raise VariableError.new(self, :format, 'to be a strftime format', @vars[:format]) unless @vars[:format].is_a?(String) raise VariableError.new(self, :order, 'to be in [:asc, :desc]', @order) \ unless %i[asc desc].include?(@order = @vars[:order]) @starting, @ending = @vars[:period] raise VariableError.new(self, :period, 'to be a an Array of min and max TimeWithZone instances', @vars[:period]) \ unless @starting.is_a?(ActiveSupport::TimeWithZone) \ && @ending.is_a?(ActiveSupport::TimeWithZone) && @starting <= @ending end
def initialize(**vars) # rubocop:disable Lint/MissingSuper
Merge and validate the options, do some simple arithmetic and set a few instance variables
def initialize(**vars) # rubocop:disable Lint/MissingSuper raise InternalError, 'Pagy::Calendar::Unit is a base class; use one of its subclasses' \ if instance_of?(Pagy::Calendar::Unit) assign_vars({ **Pagy::DEFAULT, **self.class::DEFAULT }, vars) assign_and_check(page: 1) assign_unit_vars check_overflow assign_prev_and_next end
def label(opts = {})
def label(opts = {}) label_for(@page, opts) end
def label_for(page, opts = {})
def label_for(page, opts = {}) opts[:format] ||= @vars[:format] localize(starting_time_for(page.to_i), opts) # page could be a string end
def localize(time, opts)
def localize(time, opts) time.strftime(opts[:format]) end
def page_at(time, **opts)
In case of out of range time, the :fit_time option avoids the outOfRangeError
The page that includes time
def page_at(time, **opts) fit_time = time fit_final = @final - 1 unless time.between?(@initial, fit_final) raise OutOfRangeError.new(self, :time, "between #{@initial} and #{fit_final}", time) unless opts[:fit_time] if time < @final fit_time = @initial ordinal = 'first' else fit_time = fit_final ordinal = 'last' end warn "Pagy::Calendar#page_at: Rescued #{time} out of range by returning the #{ordinal} page." end offset = page_offset_at(fit_time) # offset starts from 0 @order == :asc ? offset + 1 : @last - offset end
def page_offset_at(*)
def page_offset_at(*) raise NoMethodError, 'the page_offset_at method must be implemented by the unit subclass' end
def starting_time_for(*)
:nocov:
def starting_time_for(*) raise NoMethodError, 'the starting_time_for method must be implemented by the unit subclass' end
def time_offset_for(page)
Number of time units to offset from the @initial time, in order to get the ordered starting time for the page.
def time_offset_for(page) @order == :asc ? page - 1 : @last - page end