Class: MonoVM::Whois::Parser::Base
- Inherits:
-
Object
- Object
- MonoVM::Whois::Parser::Base
- Defined in:
- lib/monovm/whois/parser/base.rb
Overview
Shared scaffolding for record parsers.
Subclasses say which responses they understand (#applicable?) and how to
turn one into a Record (#parse). Date parsing lives here because it is
the one job every registry does differently and none of them do well: the
same field arrives as 2026-08-13T04:00:00Z, 13-Aug-2026, 2026.08.13 or
13/08/2026, and getting it wrong by a month is worse than returning nil.
Constant Summary collapse
- DATE_FORMATS =
Explicit formats, tried in order, before falling back to Ruby's parser.
Ordering matters for the ambiguous ones:
13/08/2026is day-first everywhere that writes it with slashes in a WHOIS record, so that pattern comes before the month-first reading Time.parse would pick. [ "%Y-%m-%dT%H:%M:%S%z", "%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%S.%L%z", "%Y-%m-%d %H:%M:%S%z", "%Y-%m-%d %H:%M:%S", "%Y-%m-%d", "%Y.%m.%d %H:%M:%S", "%Y.%m.%d", "%Y/%m/%d", "%d-%b-%Y %H:%M:%S", "%d-%b-%Y", "%d.%m.%Y %H:%M:%S", "%d.%m.%Y", "%d/%m/%Y %H:%M:%S", "%d/%m/%Y", "%b %d %Y", "%d %b %Y", "%Y%m%d" ].freeze
- PLAUSIBLE_YEARS =
Registration dates are never before the DNS existed and never centuries away. The range is what makes the ambiguous formats safe to try in order: "%Y.%m.%d" happily parses "12.5.2015" as year 12, month 5, day 2015 — rolling over into May of year 12 — and without this guard that nonsense wins before "%d.%m.%Y" is ever tried, silently misdating every European record.
(1980..2200)
Class Method Summary collapse
-
.snake_case(klass) ⇒ Object
IcannRddbecomes"icann_rdd".
Instance Method Summary collapse
Class Method Details
.snake_case(klass) ⇒ Object
IcannRdd becomes "icann_rdd". Handles an anonymous class, whose
Module#name is nil — which a spec or a host application defining a parser
inline would otherwise crash on.
36 37 38 39 40 |
# File 'lib/monovm/whois/parser/base.rb', line 36 def self.snake_case(klass) base = klass.name.to_s.split("::").last base = klass.inspect if base.nil? || base.empty? base.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase end |
Instance Method Details
#applicable?(response) ⇒ Boolean
19 20 21 |
# File 'lib/monovm/whois/parser/base.rb', line 19 def applicable?(response) raise NotImplementedError, "#{self.class} must implement #applicable?" end |
#name ⇒ Object
29 30 31 |
# File 'lib/monovm/whois/parser/base.rb', line 29 def name @name ||= Base.snake_case(self.class) end |
#parse(response) ⇒ Record
25 26 27 |
# File 'lib/monovm/whois/parser/base.rb', line 25 def parse(response) raise NotImplementedError, "#{self.class} must implement #parse" end |