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
588 def initialize
589   @formats = Hash.new { |hash, str| hash[str] = internal_parse(str) }
590 end

Public Instance Methods

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

Private Instance Methods

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