Sha256: ce4ca1c3e4b8b05b76d35a8e89cbef26ecf3ccae7858599678b3ed9296ee3f23

Contents?: true

Size: 1.96 KB

Versions: 7

Compression:

Stored size: 1.96 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)) || raise(InvalidPeriodIdentifierError)
        period.offset(offset.gsub(/\s+/, "").to_i)
      end

      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

      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
    end
  end
end

Version data entries

7 entries across 7 versions & 1 rubygems

Version Path
timeboss-1.1.5 lib/timeboss/calendar/parser.rb
timeboss-1.1.4 lib/timeboss/calendar/parser.rb
timeboss-1.1.3 lib/timeboss/calendar/parser.rb
timeboss-1.1.2 lib/timeboss/calendar/parser.rb
timeboss-1.1.1 lib/timeboss/calendar/parser.rb
timeboss-1.1.0 lib/timeboss/calendar/parser.rb
timeboss-1.0.5 lib/timeboss/calendar/parser.rb