Class: ActiveSupport::Duration::ISO8601Parser
Do not use. This class is for internal use only.
Relationships & Source Files | |
Namespace Children | |
Exceptions:
| |
Inherits: | Object |
Defined in: | activesupport/lib/active_support/duration/iso8601_parser.rb |
Overview
Parses a string formatted according to ISO 8601 ::ActiveSupport::Duration
into the hash.
See ISO 8601 for more information.
This parser allows negative parts to be present in pattern.
Constant Summary
-
COMMA =
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 17","
-
DATE_COMPONENT =
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 22/(-?\d(?:[.,]\d)?)(Y|M|D|W)/
-
DATE_COMPONENTS =
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 28[:years, :months, :days]
-
DATE_MARKER =
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 20/P/
-
DATE_TO_PART =
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 25{ "Y" => :years, "M" => :months, "W" => :weeks, "D" => :days }
-
PERIOD =
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 16"."
-
PERIOD_OR_COMMA =
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 15/\.|,/
-
SIGN_MARKER =
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 19/\A-|\+|/
-
TIME_COMPONENT =
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 23/(-?\d(?:[.,]\d)?)(H|M|S)/
-
TIME_COMPONENTS =
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 29[:hours, :minutes, :seconds]
-
TIME_MARKER =
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 21/T/
-
TIME_TO_PART =
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 26{ "H" => :hours, "M" => :minutes, "S" => :seconds }
Class Method Summary
- .new(string) ⇒ ISO8601Parser constructor
Instance Attribute Summary
- #mode rw
- #parts readonly
- #scanner readonly
- #sign rw
- #finished? ⇒ Boolean readonly private
Instance Method Summary
- #parse!
-
#number
private
Parses number which can be a float with either comma or period.
- #raise_parsing_error(reason = nil) private
- #scan(pattern) private
-
#validate!
private
Checks for various semantic errors as stated in ISO 8601 standard.
Constructor Details
.new(string) ⇒ ISO8601Parser
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 34
def initialize(string) @scanner = StringScanner.new(string) @parts = {} @mode = :start @sign = 1 end
Instance Attribute Details
#finished? ⇒ Boolean
(readonly, private)
[ GitHub ]
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 83
def finished? scanner.eos? end
#mode (rw)
[ GitHub ]# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 32
attr_accessor :mode, :sign
#parts (readonly)
[ GitHub ]# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 31
attr_reader :parts, :scanner
#scanner (readonly)
[ GitHub ]# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 31
attr_reader :parts, :scanner
#sign (rw)
[ GitHub ]# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 32
attr_accessor :mode, :sign
Instance Method Details
#number (private)
Parses number which can be a float with either comma or period.
#parse!
[ GitHub ]# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 41
def parse! while !finished? case mode when :start if scan(SIGN_MARKER) self.sign = (scanner.matched == "-") ? -1 : 1 self.mode = :sign else raise_parsing_error end when :sign if scan(DATE_MARKER) self.mode = :date else raise_parsing_error end when :date if scan(TIME_MARKER) self.mode = :time elsif scan(DATE_COMPONENT) parts[DATE_TO_PART[scanner[2]]] = number * sign else raise_parsing_error end when :time if scan(TIME_COMPONENT) parts[TIME_TO_PART[scanner[2]]] = number * sign else raise_parsing_error end end end validate! parts end
#raise_parsing_error(reason = nil) (private)
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 96
def raise_parsing_error(reason = nil) raise ParsingError, "Invalid ISO 8601 duration: #{scanner.string.inspect} #{reason}".strip end
#scan(pattern) (private)
[ GitHub ]# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 92
def scan(pattern) scanner.scan(pattern) end
#validate! (private)
Checks for various semantic errors as stated in ISO 8601 standard.
# File 'activesupport/lib/active_support/duration/iso8601_parser.rb', line 101
def validate! raise_parsing_error("is empty duration") if parts.empty? # Mixing any of Y, M, D with W is invalid. if parts.key?(:weeks) && parts.keys.intersect?(DATE_COMPONENTS) raise_parsing_error("mixing weeks with other date parts not allowed") end # Specifying an empty T part is invalid. if mode == :time && !parts.keys.intersect?(TIME_COMPONENTS) raise_parsing_error("time part marker is present but time part is empty") end fractions = parts.values.reject(&:zero?).select { |a| (a % 1) != 0 } unless fractions.empty? || (fractions.size == 1 && fractions.last == @parts.values.reject(&:zero?).last) raise_parsing_error "(only last part can be fractional)" end true end