class TimeBoss::Calendar::Parser

Constants

InvalidPeriodIdentifierError
RANGE_DELIMITER

Attributes

calendar[R]

Public Class Methods

new(calendar) click to toggle source
# File lib/timeboss/calendar/parser.rb, line 10
def initialize(calendar)
  @calendar = calendar
end

Public Instance Methods

parse(identifier = nil) click to toggle source
# File lib/timeboss/calendar/parser.rb, line 14
def parse(identifier = nil)
  return nil unless (identifier || "").strip.length > 0
  return parse_identifier(identifier) unless identifier&.include?(RANGE_DELIMITER)
  bases = identifier.split(RANGE_DELIMITER).map { |i| parse_identifier(i.strip) } unless identifier.nil?
  bases ||= [parse_identifier(nil)]
  Period.new(calendar, *bases)
rescue ArgumentError
  raise InvalidPeriodIdentifierError
end

Private Instance Methods

parse_identifier(identifier) click to toggle source
# File lib/timeboss/calendar/parser.rb, line 26
def parse_identifier(identifier)
  captures = identifier&.match(/^([^-]+)(\s*[+-]\s*[0-9]+)$/)&.captures
  base, offset = captures || [identifier, "0"]
  (period = parse_period(base&.strip)) || raise(InvalidPeriodIdentifierError)
  period.offset(offset.gsub(/\s+/, "").to_i)
end
parse_period(identifier) click to toggle source
# File lib/timeboss/calendar/parser.rb, line 33
def parse_period(identifier)
  return calendar.public_send(identifier) if calendar.respond_to?(identifier.to_s)
  parse_term(identifier || Date.today.year.to_s)
end
parse_term(identifier) click to toggle source
# File lib/timeboss/calendar/parser.rb, line 38
def parse_term(identifier)
  return Day.new(calendar, Date.parse(identifier)) if identifier.match?(/^[0-9]{4}-?[01][0-9]-?[0-3][0-9]$/)

  raise InvalidPeriodIdentifierError unless identifier.match?(/^[HQMWD0-9]+$/)
  period = identifier.to_i == 0 ? calendar.this_year : calendar.year(identifier.to_i)
  %w[half quarter month week day].each do |size|
    prefix = size[0].upcase
    next unless identifier.include?(prefix)
    junk, identifier = identifier.split(prefix)
    raise InvalidPeriodIdentifierError if junk.match?(/\D/)
    (period = period.public_send(size.pluralize)[identifier.to_i - 1]) || raise(InvalidPeriodIdentifierError)
  end
  period
end