class Montrose::Options

Attributes

default_every[RW]
default_starts[W]
default_until[W]

Public Class Methods

def_option(name) click to toggle source
# File lib/montrose/options.rb, line 22
def def_option(name)
  defined_options << name.to_sym
  attr_accessor name
  protected :"#{name}="
end
default_options() click to toggle source
# File lib/montrose/options.rb, line 77
def default_options
  {
    until: default_until,
    interval: 1
  }
end
default_starts() click to toggle source

Return the default starting time.

@example Recurrence.default_starts #=> <Date>

# File lib/montrose/options.rb, line 55
def default_starts
  ::Montrose::Utils.normalize_time determine_default_starts
end
default_until() click to toggle source

Return the default ending time.

@example Recurrence.default_until #=> <Date>

# File lib/montrose/options.rb, line 35
def default_until
  ::Montrose::Utils.normalize_time determine_default_until
end
defined_options() click to toggle source
# File lib/montrose/options.rb, line 18
def defined_options
  @defined_options ||= []
end
determine_default_starts() click to toggle source

private

# File lib/montrose/options.rb, line 60
def determine_default_starts
  case @default_starts
  when String
    ::Montrose::Utils.parse_time(@default_starts)
  when Proc
    @default_starts.call
  when nil
    ::Montrose::Utils.current_time
  else
    @default_starts
  end
end
determine_default_until() click to toggle source

private

# File lib/montrose/options.rb, line 40
def determine_default_until
  case @default_until
  when String
    ::Montrose::Utils.parse_time(@default_until)
  when Proc
    @default_until.call
  else
    @default_until
  end
end
merge(opts = {}) click to toggle source
# File lib/montrose/options.rb, line 73
def merge(opts = {})
  new(default_options).merge(opts)
end
new(options = {}) click to toggle source
Calls superclass method
# File lib/montrose/options.rb, line 12
def new(options = {})
  return options if options.is_a?(self)

  super
end
new(opts = {}) click to toggle source
# File lib/montrose/options.rb, line 106
def initialize(opts = {})
  defaults = {
    every: self.class.default_every,
    interval: nil,
    starts: nil,
    until: nil,
    day: nil,
    mday: nil,
    yday: nil,
    week: nil,
    month: nil,
    total: nil,
    week_start: nil,
    exclude_end: nil
  }

  options = defaults.merge(opts || {})
  options.each { |(k, v)| self[k] ||= v unless v.nil? }
end

Public Instance Methods

[](option) click to toggle source
# File lib/montrose/options.rb, line 138
def [](option)
  send(:"#{option}")
end
[]=(option, val) click to toggle source
# File lib/montrose/options.rb, line 134
def []=(option, val)
  send(:"#{option}=", val)
end
at=(time) click to toggle source
# File lib/montrose/options.rb, line 233
def at=(time)
  @at = map_arg(time) { |t| time_of_day_parse(t).parts }
end
between=(range) click to toggle source
# File lib/montrose/options.rb, line 225
def between=(range)
  if Montrose.enable_deprecated_between_masking?
    @covering = range
  end
  self[:starts] = range.first unless self[:starts]
  self[:until] = range.last unless self[:until]
end
day=(days) click to toggle source
# File lib/montrose/options.rb, line 205
def day=(days)
  @day = Day.parse(days)
end
during=(during_arg) click to toggle source
# File lib/montrose/options.rb, line 191
def during=(during_arg)
  @during = decompose_during_arg(during_arg)
    .each_with_object([]) { |(time_of_day_first, time_of_day_last), all|
    if time_of_day_last < time_of_day_first
      all.push(
        [time_of_day_first.parts, end_of_day.parts],
        [beginning_of_day.parts, time_of_day_last.parts]
      )
    else
      all.push([time_of_day_first.parts, time_of_day_last.parts])
    end
  }.presence
end
every=(arg) click to toggle source
# File lib/montrose/options.rb, line 164
def every=(arg)
  parsed = parse_frequency(arg)

  self[:interval] = parsed[:interval] if parsed[:interval]

  @every = parsed.fetch(:every)
end
Also aliased as: frequency=
except=(date) click to toggle source
# File lib/montrose/options.rb, line 245
def except=(date)
  @except = map_arg(date) { |d| as_date(d) }
end
fetch(key, *args) { || ... } click to toggle source
# File lib/montrose/options.rb, line 149
def fetch(key, *args)
  raise ArgumentError, "wrong number of arguments (#{args.length} for 1..2)" if args.length > 1

  found = send(key)
  return found if found
  return args.first if args.length == 1
  raise KeyError, "Key #{key.inspect} not found" unless block_given?

  yield
end
frequency=(arg)
Alias for: every=
hour=(hours) click to toggle source
# File lib/montrose/options.rb, line 187
def hour=(hours)
  @hour = map_arg(hours) { |h| assert_hour(h) }
end
inspect() click to toggle source
# File lib/montrose/options.rb, line 249
def inspect
  "#<#{self.class} #{to_h.inspect}>"
end
key?(key) click to toggle source
# File lib/montrose/options.rb, line 160
def key?(key)
  respond_to?(key) && !send(key).nil?
end
mday=(mdays) click to toggle source
# File lib/montrose/options.rb, line 209
def mday=(mdays)
  @mday = MonthDay.parse(mdays)
end
merge(other) click to toggle source
# File lib/montrose/options.rb, line 142
def merge(other)
  h1 = to_hash
  h2 = other.to_hash

  self.class.new(h1.merge(h2))
end
minute=(minutes) click to toggle source
# File lib/montrose/options.rb, line 183
def minute=(minutes)
  @minute = Minute.parse(minutes)
end
month=(months) click to toggle source
# File lib/montrose/options.rb, line 221
def month=(months)
  @month = Month.parse(months)
end
on=(arg) click to toggle source
# File lib/montrose/options.rb, line 237
def on=(arg)
  result = decompose_on_arg(arg)
  self[:day] = result[:day] if result[:day]
  self[:month] = result[:month] if result[:month]
  self[:mday] = result[:mday] if result[:mday]
  @on = arg
end
start_time() click to toggle source
# File lib/montrose/options.rb, line 253
def start_time
  time = starts || default_starts

  if at
    at.map { |hour, min, sec = 0| time.change(hour: hour, min: min, sec: sec) }
      .select { |t| t >= time }
      .min || time
  else
    time
  end
end
starts=(time) click to toggle source
# File lib/montrose/options.rb, line 175
def starts=(time)
  @starts = normalize_time(as_time(time)) || default_starts
end
to_h()
Alias for: to_hash
to_hash() click to toggle source
# File lib/montrose/options.rb, line 126
def to_hash
  hash_pairs = self.class.defined_options.flat_map { |opt_name|
    [opt_name, send(opt_name)]
  }
  Hash[*hash_pairs].reject { |_k, v| v.nil? }
end
Also aliased as: to_h
until=(time) click to toggle source
# File lib/montrose/options.rb, line 179
def until=(time)
  @until = normalize_time(as_time(time)) || default_until
end
week=(weeks) click to toggle source
# File lib/montrose/options.rb, line 217
def week=(weeks)
  @week = Week.parse(weeks)
end
yday=(ydays) click to toggle source
# File lib/montrose/options.rb, line 213
def yday=(ydays)
  @yday = YearDay.parse(ydays)
end

Private Instance Methods

assert_hour(hour) click to toggle source
# File lib/montrose/options.rb, line 281
def assert_hour(hour)
  assert_range_includes(1..::Montrose::Utils::MAX_HOURS_IN_DAY, hour)
end
assert_range_includes(range, item, absolute = false) click to toggle source
# File lib/montrose/options.rb, line 309
def assert_range_includes(range, item, absolute = false)
  test = absolute ? item.abs : item
  raise ConfigurationError, "Out of range: #{range.inspect} does not include #{test}" unless range.include?(test)

  item
end
beginning_of_day() click to toggle source
# File lib/montrose/options.rb, line 370
def beginning_of_day
  @beginning_of_day ||= time_of_day_parse(Time.now.beginning_of_day)
end
decompose_during_arg(during_arg) click to toggle source
# File lib/montrose/options.rb, line 342
def decompose_during_arg(during_arg)
  case during_arg
  when Range
    [decompose_during_parts(during_arg)]
  else
    map_arg(during_arg) { |d| decompose_during_parts(d) } || []
  end
end
decompose_during_parts(during_parts) click to toggle source
# File lib/montrose/options.rb, line 351
def decompose_during_parts(during_parts)
  case during_parts
  when Range
    decompose_during_parts([during_parts.first, during_parts.last])
  when String
    decompose_during_parts(during_parts.split(/[-—–]/))
  else
    during_parts.map { |parts| time_of_day_parse(parts) }
  end
end
decompose_on_arg(arg) click to toggle source
# File lib/montrose/options.rb, line 285
def decompose_on_arg(arg)
  case arg
  when Hash
    arg.each_with_object({}) do |(k, v), result|
      key, val = month_or_day(k)
      result[key] = val
      result[:mday] ||= []
      result[:mday] += Montrose::MonthDay.parse(v)
    end
  else
    {day: Montrose::Day.parse(arg)}
  end
end
default_starts() click to toggle source
# File lib/montrose/options.rb, line 267
def default_starts
  self.class.default_starts
end
default_until() click to toggle source
# File lib/montrose/options.rb, line 271
def default_until
  self.class.default_until
end
duration_to_frequency_parts(duration) click to toggle source
# File lib/montrose/options.rb, line 338
def duration_to_frequency_parts(duration)
  duration.parts.first
end
end_of_day() click to toggle source
# File lib/montrose/options.rb, line 366
def end_of_day
  @end_of_day ||= time_of_day_parse(Time.now.end_of_day)
end
map_arg(arg, &block) click to toggle source
# File lib/montrose/options.rb, line 275
def map_arg(arg, &block)
  return nil unless arg

  Array(arg).map(&block)
end
month_or_day(key) click to toggle source
# File lib/montrose/options.rb, line 299
def month_or_day(key)
  month = Montrose::Month.number(key)
  return [:month, month] if month

  day = Montrose::Day.number(key)
  return [:day, day] if day

  raise ConfigurationError, "Did not recognize #{key} as a month or day"
end
numeric_to_frequency_parts(number) click to toggle source
# File lib/montrose/options.rb, line 328
def numeric_to_frequency_parts(number)
  parts = nil
  %i[year month week day hour minute].each do |freq|
    div, mod = number.divmod(1.send(freq))
    parts = [freq, div]
    return parts if mod.zero?
  end
  parts
end
parse_frequency(input) click to toggle source
# File lib/montrose/options.rb, line 316
def parse_frequency(input)
  if input.respond_to?(:parts)
    frequency, interval = duration_to_frequency_parts(input)
    {every: frequency.to_s.singularize.to_sym, interval: interval}
  elsif input.is_a?(Numeric)
    frequency, interval = numeric_to_frequency_parts(input)
    {every: frequency, interval: interval}
  else
    {every: Frequency.assert(input)}
  end
end
time_of_day_parse(time_parts) click to toggle source
# File lib/montrose/options.rb, line 362
def time_of_day_parse(time_parts)
  ::Montrose::TimeOfDay.parse(time_parts)
end