lib/timezone/lookup.rb
# frozen_string_literal: true
require 'timezone/lookup/geonames'
require 'timezone/lookup/google'
require 'timezone/lookup/test'
require 'timezone/net_http_client'
require 'ostruct'
module Timezone
# Configure timezone lookups.
module Lookup
class << self
MISSING_LOOKUP = 'No lookup configured'
private_constant :MISSING_LOOKUP
# Returns the lookup object
#
# @return [#lookup] the lookup object
# @raise [Timezone::Error::InvalidConfig] if the lookup has not
# been configured
def lookup
@lookup || raise(::Timezone::Error::InvalidConfig, MISSING_LOOKUP)
end
# Configure a lookup object
#
# @param lookup [:google, :geonames, :test] use a built-in lookup
# @param lookup [Class] a custom lookup class
# @yieldparam [OpenStruct] an object on which to set configuration
# options
#
# @return [#lookup] the lookup object
def config(lookup)
options = OptionSetter.new(lookup)
yield(options.config) if block_given?
@lookup = options.make_lookup
end
end
# Responsible for collecting options in the DSL and creating
# lookup objects using those options.
class OptionSetter
LOOKUPS = {
geonames: ::Timezone::Lookup::Geonames,
google: ::Timezone::Lookup::Google,
test: ::Timezone::Lookup::Test
}.freeze
INVALID_LOOKUP = 'Invalid lookup specified'
attr_reader :config
def initialize(lookup)
if lookup.is_a?(Symbol)
lookup = LOOKUPS.fetch(lookup) do
raise ::Timezone::Error::InvalidConfig, INVALID_LOOKUP
end
end
@lookup = lookup
@config = OpenStruct.new
end
def make_lookup
config.request_handler ||= ::Timezone::NetHTTPClient
@lookup.new(config)
end
end
private_constant :OptionSetter
end
end