class Cyclical::WeekdaysFilter

Constants

WEEKDAYS
WEEKDAY_NAMES

Attributes

ordered_weekdays[R]
rule[R]
weekdays[R]

Public Class Methods

new(*weekdays) click to toggle source
# File lib/cyclical/filters/weekdays_filter.rb, line 18
def initialize(*weekdays)
  @rule = weekdays.shift if weekdays.first.is_a?(Rule)

  raise ArgumentError, "Specify at least one weekday" if weekdays.empty?
  @ordered_weekdays = {}

  if weekdays.last.respond_to?(:has_key?)
    raise ArgumentError, "No recurrence rule given for ordered weekdays filter" if @rule.nil?

    weekdays.last.each do |day, orders|
      day = day.is_a?(Integer) ? day : WEEKDAYS[day]
      orders = [orders] unless orders.respond_to?(:each)

      @ordered_weekdays[WEEKDAY_NAMES[day]] = orders.sort
    end
    weekdays = weekdays[0..-2]
  end

  @weekdays = weekdays.map { |w| w.is_a?(Integer) ? w : WEEKDAYS[w.to_sym] }.sort
end

Public Instance Methods

match?(date) click to toggle source
# File lib/cyclical/filters/weekdays_filter.rb, line 39
def match?(date)
  return true if weekdays.include?(date.wday)

  day = WEEKDAY_NAMES[date.wday]
  return false if ordered_weekdays[day].nil?

  first, occ, max = order_in_interval(date)

  return (ordered_weekdays[day].include?(occ) || ordered_weekdays[day].include?(occ - max - 1))
end
next(date) click to toggle source

FIXME - this can probably be calculated

# File lib/cyclical/filters/weekdays_filter.rb, line 55
def next(date)
  until match?(date)
    date += 1.day
  end

  date
end
previous(date) click to toggle source
# File lib/cyclical/filters/weekdays_filter.rb, line 63
def previous(date)
  until match?(date)
    date -= 1.day
  end

  date
end
step() click to toggle source
# File lib/cyclical/filters/weekdays_filter.rb, line 50
def step
  1.day
end

Private Instance Methods

order_in_interval(date) click to toggle source
# File lib/cyclical/filters/weekdays_filter.rb, line 73
def order_in_interval(date)
  case @rule
  when YearlyRule
    first = (7 + date.wday - date.beginning_of_year.wday) % 7 + 1
    occ = (date.yday - first) / 7 + 1
    max = (date.end_of_year.yday - first) / 7 + 1
  when MonthlyRule
    first = (7 + date.wday - date.beginning_of_month.wday) % 7 + 1
    occ = (date.day - first) / 7 + 1
    max = (date.end_of_month.day - first) / 7 + 1
  else
    raise RuntimeError, "Ordered weekdays filter only supports monthy and yearly rules. (#{@rule.class} given)"
  end

  [first, occ, max]
end