class Pagy::Calendar

Calendar class
:nodoc:

def calendar_at(time, **opts)

Return the calendar object at time
def calendar_at(time, **opts)
  conf        = Marshal.load(Marshal.dump(@conf))
  page_params = {}
  @units.inject(nil) do |object, unit|
    conf[unit][:period] = object&.send(:active_period) || @period
    conf[unit][:page]   = page_params[:"#{unit}_#{@page_param}"] \
                        = Calendar.send(:create, unit, **conf[unit]).send(:page_at, time, **opts)
    conf[unit][:params] ||= {}
    conf[unit][:params].merge!(page_params)
    Calendar.send(:create, unit, **conf[unit])
  end
end

def create(unit, **vars)

Create a unit subclass instance by using the unit name (internal use)
def create(unit, **vars)
  raise InternalError, "unit must be in #{UNITS.inspect}; got #{unit}" unless UNITS.include?(unit)
  name    = unit.to_s
  name[0] = name[0].capitalize
  Object.const_get("Pagy::Calendar::#{name}").new(**vars)
end

def init(...)

Return calendar, from, to
def init(...)
  new.send(:init, ...)
end

def init(conf, period, params)

Create the calendar
def init(conf, period, params)
  @conf  = Marshal.load(Marshal.dump(conf))  # store a copy
  @units = Calendar::UNITS & @conf.keys # get the units in time length desc order
  raise ArgumentError, 'no calendar unit found in pagy_calendar @configuration' if @units.empty?
  @period     = period
  @params     = params
  @page_param = conf[:pagy][:page_param] || DEFAULT[:page_param]
  # set all the :page_param vars for later deletion
  @units.each { |unit| conf[unit][:page_param] = :"#{unit}_#{@page_param}" }
  calendar = {}
  object   = nil
  @units.each_with_index do |unit, index|
    params_to_delete    = @units[(index + 1), @units.size].map { |sub| conf[sub][:page_param] } + [@page_param]
    conf[unit][:params] = ->(up) { up.except(*params_to_delete.map(&:to_s)) }
    conf[unit][:period] = object&.send(:active_period) || @period
    conf[unit][:page]   = @params[:"#{unit}_#{@page_param}"] # requested page
    # :nocov:
    conf[unit][:counts] = yield(unit, conf[unit][:period]) if block_given?  # nocov doesn't need to fail block_given?
    # :nocov:
    calendar[unit]      = object \
                        = Calendar.send(:create, unit, **conf[unit])
  end
  [replace(calendar), object.from, object.to]
end

def showtime

Return the current time of the smallest time unit shown
def showtime
  self[@units.last].from
end