diff --git a/lib/http/chainable.rb b/lib/http/chainable.rb index 00188d27..d63feea7 100644 --- a/lib/http/chainable.rb +++ b/lib/http/chainable.rb @@ -94,27 +94,7 @@ def timeout(options) klass, options = case options when Numeric then [HTTP::Timeout::Global, {:global_timeout => options}] when Hash - options = options.dup - %i[read write connect].each do |k| - next unless options.key? k - - if options.key?("#{k}_timeout".to_sym) - raise ArgumentError, "can't pass both #{k} and #{"#{k}_timeout".to_sym}" - end - - options["#{k}_timeout".to_sym] = options.delete k - end - - options.each do |key, value| - unless HTTP::Timeout::PerOperation::SETTINGS.member?(key) && value.is_a?(Numeric) - raise ArgumentError, "invalid option #{key.inspect}, must be numeric " \ - "`.timeout(connect: x, write: y, read: z)`." - end - end - - raise ArgumentError, "at least one option" if options.empty? - - [HTTP::Timeout::PerOperation, options.dup] + [HTTP::Timeout::PerOperation, HTTP::Timeout::PerOperation.parse_options(options)] when :null then [HTTP::Timeout::Null, {}] else raise ArgumentError, "Use `.timeout(:null)`, " \ "`.timeout(global_timeout_in_seconds)` or " \ diff --git a/lib/http/timeout/per_operation.rb b/lib/http/timeout/per_operation.rb index f80d751f..8c70731d 100644 --- a/lib/http/timeout/per_operation.rb +++ b/lib/http/timeout/per_operation.rb @@ -12,6 +12,39 @@ class PerOperation < Null READ_TIMEOUT = 0.25 SETTINGS = Set.new(%i[read_timeout write_timeout connect_timeout]) + + class << self + def parse_options(options) + options = options.dup.then { |opts| expand_names(opts) } + options.each do |key, value| + unless SETTINGS.member?(key) && value.is_a?(Numeric) + raise ArgumentError, "invalid option #{key.inspect}, must be numeric " \ + "`.timeout(connect: x, write: y, read: z)`." + end + end + + raise ArgumentError, "at least one option" if options.empty? + + options + end + + private + + def expand_names(options) + %i[read write connect].each do |k| + next unless options.key? k + + if options.key?("#{k}_timeout".to_sym) + raise ArgumentError, "can't pass both #{k} and #{"#{k}_timeout".to_sym}" + end + + options["#{k}_timeout".to_sym] = options.delete k + end + + options + end + end + def initialize(*args) super