Sha256: b407747c74b3e94b45ce38cb5bb7ef81ab12162d05105c97e8e7ddc2e39c6ef7
Contents?: true
Size: 1.95 KB
Versions: 4
Compression:
Stored size: 1.95 KB
Contents
# frozen_string_literal: true module TimeBoss class Calendar class Parser RANGE_DELIMITER = '..' InvalidPeriodIdentifierError = Class.new(StandardError) attr_reader :calendar def initialize(calendar) @calendar = calendar end 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 def parse_identifier(identifier) captures = identifier&.match(/^([^-]+)(\s*[+-]\s*[0-9]+)$/)&.captures base, offset = captures || [identifier, '0'] period = parse_period(base&.strip) or raise InvalidPeriodIdentifierError period.offset(offset.gsub(/\s+/, '').to_i) end def parse_period(identifier) return calendar.send(identifier) if calendar.respond_to?(identifier.to_s) parse_term(identifier || Date.today.year.to_s) end 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 = if identifier.to_i == 0 then calendar.this_year else calendar.year(identifier.to_i) end %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.send(size.pluralize)[identifier.to_i - 1] or raise InvalidPeriodIdentifierError end period end end end end
Version data entries
4 entries across 4 versions & 1 rubygems