class Puppet::Pops::Time::Timespan::FormatParser

Parses a string into a Timestamp::Format instance

Constants

DAY_MAX
HOUR_MAX
MIN_MAX
MSEC_MAX
NSEC_MAX
SEC_MAX
SEGMENT_CLASS_BY_ORDINAL
STATE_LITERAL

States used by the internal_parser function

STATE_PAD
STATE_WIDTH

Public Class Methods

new() click to toggle source
    # File lib/puppet/pops/time/timespan.rb
589 def initialize
590   @formats = Hash.new { |hash, str| hash[str] = internal_parse(str) }
591 end

Public Instance Methods

parse_format(format) click to toggle source
    # File lib/puppet/pops/time/timespan.rb
593 def parse_format(format)
594   @formats[format]
595 end

Private Instance Methods

append_literal(bld, codepoint) click to toggle source
    # File lib/puppet/pops/time/timespan.rb
614 def append_literal(bld, codepoint)
615   if bld.empty? || !bld.last.is_a?(Format::LiteralSegment)
616     bld << Format::LiteralSegment.new(String.new.concat(codepoint))
617   else
618     bld.last.concat(codepoint)
619   end
620 end
bad_format_specifier(format, start, position) click to toggle source
    # File lib/puppet/pops/time/timespan.rb
610 def bad_format_specifier(format, start, position)
611   _("Bad format specifier '%{expression}' in '%{format}', at position %{position}") % { expression: format[start,position-start], format: format, position: position }
612 end
internal_parse(str) click to toggle source
    # File lib/puppet/pops/time/timespan.rb
627 def internal_parse(str)
628   bld = []
629   raise ArgumentError, _('Format must be a String') unless str.is_a?(String)
630   highest = -1
631   state = STATE_LITERAL
632   padchar = '0'
633   width = nil
634   position = -1
635   fstart = 0
636 
637   str.codepoints do |codepoint|
638     position += 1
639     if state == STATE_LITERAL
640       if codepoint == 0x25 # '%'
641         state = STATE_PAD
642         fstart = position
643         padchar = '0'
644         width = nil
645       else
646         append_literal(bld, codepoint)
647       end
648       next
649     end
650 
651     case codepoint
652     when 0x25 # '%'
653       append_literal(bld, codepoint)
654       state = STATE_LITERAL
655     when 0x2D # '-'
656       raise ArgumentError, bad_format_specifier(str, fstart, position) unless state == STATE_PAD
657       padchar = nil
658       state = STATE_WIDTH
659     when 0x5F # '_'
660       raise ArgumentError, bad_format_specifier(str, fstart, position) unless state == STATE_PAD
661       padchar = ' '
662       state = STATE_WIDTH
663     when 0x44 # 'D'
664       highest = DAY_MAX
665       bld << Format::DaySegment.new(padchar, width)
666       state = STATE_LITERAL
667     when 0x48 # 'H'
668       highest = HOUR_MAX unless highest > HOUR_MAX
669       bld << Format::HourSegment.new(padchar, width)
670       state = STATE_LITERAL
671     when 0x4D # 'M'
672       highest = MIN_MAX unless highest > MIN_MAX
673       bld << Format::MinuteSegment.new(padchar, width)
674       state = STATE_LITERAL
675     when 0x53 # 'S'
676       highest = SEC_MAX unless highest > SEC_MAX
677       bld << Format::SecondSegment.new(padchar, width)
678       state = STATE_LITERAL
679     when 0x4C # 'L'
680       highest = MSEC_MAX unless highest > MSEC_MAX
681       bld << Format::MilliSecondSegment.new(padchar, width)
682       state = STATE_LITERAL
683     when 0x4E # 'N'
684       highest = NSEC_MAX unless highest > NSEC_MAX
685       bld << Format::NanoSecondSegment.new(padchar, width)
686       state = STATE_LITERAL
687     else # only digits allowed at this point
688       raise ArgumentError, bad_format_specifier(str, fstart, position) unless codepoint >= 0x30 && codepoint <= 0x39
689       if state == STATE_PAD && codepoint == 0x30
690         padchar = '0'
691       else
692         n = codepoint - 0x30
693         if width.nil?
694           width = n
695         else
696           width = width * 10 + n
697         end
698       end
699       state = STATE_WIDTH
700     end
701   end
702 
703   raise ArgumentError, bad_format_specifier(str, fstart, position)  unless state == STATE_LITERAL
704   unless highest == -1
705     hc = SEGMENT_CLASS_BY_ORDINAL[highest]
706     bld.find { |s| s.instance_of?(hc) }.set_use_total
707   end
708   Format.new(str, bld)
709 end