# frozen_string_literal: true require "montrose/refinements/array_concat" module Montrose module Chainable using Montrose::Refinements::ArrayConcat # Create a recurrence from the given frequency # # @param frequency [Symbol,String,Numeric] the recurrence frequency # @param options [Hash] additional recurrence options # # @example # Montrose.every(:hour) # Montrose.every(:hour, interval: 2) # Montrose.every(3.days, starts: 2.days.from_now) # Montrose.every(1.year, until: 10.days.from_now) # # @return [Montrose::Recurrence] # def every(frequency, options = {}) branch options.merge(every: frequency) end # Create a minutely recurrence. # # @param options [Hash] additional recurrence options # # @example # Montrose.minutely # Montrose.minutely(interval: 2) #=> every 2 minutes # Montrose.minutely(starts: 3.days.from_now) # Montrose.minutely(until: 10.days.from_now) # Montrose.minutely(total: 5) # Montrose.minutely(except: Date.tomorrow) # # @return [Montrose::Recurrence] # def minutely(options = {}) branch options.merge(every: :minute) end # Create a hourly recurrence. # # @param options [Hash] additional recurrence options # # @example # Montrose.hourly # Montrose.hourly(interval: 2) #=> every 2 hours # Montrose.hourly(starts: 3.days.from_now) # Montrose.hourly(until: 10.days.from_now) # Montrose.hourly(total: 5) # Montrose.hourly(except: Date.tomorrow) # # @return [Montrose::Recurrence] # def hourly(options = {}) branch options.merge(every: :hour) end # Create a daily recurrence. # # @param options [Hash] additional recurrence options # # @example # Montrose.daily # Montrose.daily(interval: 2) #=> every 2 days # Montrose.daily(starts: 3.days.from_now) # Montrose.daily(until: 10.days.from_now) # Montrose.daily(total: 5) # Montrose.daily(except: Date.tomorrow) # # @return [Montrose::Recurrence] # def daily(options = {}) branch options.merge(every: :day) end # Create a weekly recurrence. # # @param options [Hash] additional recurrence options # # @example # Montrose.weekly(on: 5) #=> 0 = sunday, 1 = monday, ... # Montrose.weekly(on: :saturday) # Montrose.weekly(on: [sunday, :saturday]) # Montrose.weekly(on: :saturday, interval: 2) # Montrose.weekly(on: :saturday, total: 5) # # @return [Montrose::Recurrence] # def weekly(options = {}) branch options.merge(every: :week) end # Create a monthly recurrence. # # @param options [Hash] additional recurrence options # # @example # Montrose.monthly(mday: [2, 15]) # 2nd and 15th of the month # Montrose.monthly(mday: -3) # third-to-last day of the month # Montrose.monthly(mday: 10..15) # 10th through the 15th day of the month # # @return [Montrose::Recurrence] # def monthly(options = {}) branch options.merge(every: :month) end # Create a yearly recurrence. # # @param options [Hash] additional recurrence options # # @example # Montrose.yearly(on: [7, 14]) #=> every Jul 14 # Montrose.yearly(on: [7, 14], interval: 2) #=> every 2 years on Jul 14 # Montrose.yearly(on: [:jan, 14], interval: 2) # Montrose.yearly(on: [:january, 14], interval: 2) # Montrose.yearly(on: [:january, 14], total: 5) # # @return [Montrose::Recurrence] # def yearly(options = {}) branch options.merge(every: :year) end # Create a recurrence starting at given timestamp. # # @param starts_at [Time, Date] start time of recurrence # # @example # Montrose.daily.starting(Date.tomorrow) # # @return [Montrose::Recurrence] # def starts(starts_at) merge(starts: starts_at) end alias_method :starting, :starts # Create a recurrence ending at given timestamp. # # @param ends_at [Time, Date] end time of recurrence # # @example # Montrose.daily.ending(1.year.from_now) # # @return [Montrose::Recurrence] # def until(ends_at) merge(until: ends_at) end alias_method :ending, :until # Create a recurrence occurring between the start and end # of a given date range; :between is shorthand for separate # :starts and :until options. When used with explicit :start # and/or :until options, those will take precedence. # # @param [Range] date_range # # @example # Montrose.weekly.between(Date.today..Date.new(2016, 3, 15)) # # @return [Montrose::Recurrence] # def between(date_range) merge(between: date_range) end # Create a recurrence which will only emit values within the # date range, also called "masking." # # @param [Range] date_range # # @example # Montrose.weekly.covering(Date.tomorrow..Date.new(2016, 3, 15)) # # @return [Montrose::Recurrence] # def covering(date_range) merge(covering: date_range) end # Create a recurrence occurring within a time-of-day range or ranges. # Given time ranges will parse as times-of-day and ignore given dates. # # @param [Range