lib/faraday/options.rb in faraday-0.16.2 vs lib/faraday/options.rb in faraday-0.17.0

- old
+ new

@@ -1,7 +1,5 @@ -# frozen_string_literal: true - module Faraday # Subclasses Struct with some special helpers for converting from a Hash to # a Struct. class Options < Struct # Public @@ -10,11 +8,10 @@ end # Public def each return to_enum(:each) unless block_given? - members.each do |key| yield(key.to_sym, send(key)) end end @@ -28,11 +25,11 @@ new_value = value.dup else new_value = value end - send("#{key}=", new_value) unless new_value.nil? + self.send("#{key}=", new_value) unless new_value.nil? end self end # Public @@ -48,18 +45,14 @@ end # Public def merge!(other) other.each do |key, other_value| - self_value = send(key) + self_value = self.send(key) sub_options = self.class.options_for(key) - new_value = if self_value && sub_options && other_value - self_value.merge(other_value) - else - other_value - end - send("#{key}=", new_value) unless new_value.nil? + new_value = (self_value && sub_options && other_value) ? self_value.merge(other_value) : other_value + self.send("#{key}=", new_value) unless new_value.nil? end self end # Public @@ -74,14 +67,14 @@ # Public def fetch(key, *args) unless symbolized_key_set.include?(key.to_sym) key_setter = "#{key}=" - if !args.empty? + if args.size > 0 send(key_setter, args.first) elsif block_given? - send(key_setter, yield(key)) + send(key_setter, Proc.new.call(key)) else raise self.class.fetch_error_class, "key not found: #{key.inspect}" end end send(key) @@ -103,11 +96,10 @@ end # Public def each_key return to_enum(:each_key) unless block_given? - keys.each do |key| yield(key) end end @@ -119,11 +111,10 @@ alias has_key? key? # Public def each_value return to_enum(:each_value) unless block_given? - values.each do |value| yield(value) end end @@ -149,13 +140,13 @@ values = [] members.each do |member| value = send(member) values << "#{member}=#{value.inspect}" if value end - values = values.empty? ? '(empty)' : values.join(', ') + values = values.empty? ? ' (empty)' : (' ' << values.join(", ")) - %(#<#{self.class} #{values}>) + %(#<#{self.class}#{values}>) end # Internal def self.options(mapping) attribute_options.update(mapping) @@ -169,16 +160,12 @@ # Internal def self.attribute_options @attribute_options ||= {} end - def self.memoized(key, &block) - unless block_given? - raise ArgumentError, '#memoized must be called with a block' - end - - memoized_attributes[key.to_sym] = block + def self.memoized(key) + memoized_attributes[key.to_sym] = Proc.new class_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{key}() self[:#{key}]; end RUBY end @@ -186,37 +173,201 @@ @memoized_attributes ||= {} end def [](key) key = key.to_sym - if (method = self.class.memoized_attributes[key]) + if method = self.class.memoized_attributes[key] super(key) || (self[key] = instance_eval(&method)) else super end end def symbolized_key_set - @symbolized_key_set ||= Set.new(keys.map(&:to_sym)) + @symbolized_key_set ||= Set.new(keys.map { |k| k.to_sym }) end def self.inherited(subclass) super subclass.attribute_options.update(attribute_options) subclass.memoized_attributes.update(memoized_attributes) end def self.fetch_error_class @fetch_error_class ||= if Object.const_defined?(:KeyError) - ::KeyError - else - ::IndexError - end + ::KeyError + else + ::IndexError + end end end -end -require 'faraday/options/request_options' -require 'faraday/options/ssl_options' -require 'faraday/options/proxy_options' -require 'faraday/options/connection_options' -require 'faraday/options/env' + class RequestOptions < Options.new(:params_encoder, :proxy, :bind, + :timeout, :open_timeout, :write_timeout, :boundary, :oauth, :context) + + def []=(key, value) + if key && key.to_sym == :proxy + super(key, value ? ProxyOptions.from(value) : nil) + else + super(key, value) + end + end + end + + class SSLOptions < Options.new(:verify, :ca_file, :ca_path, :verify_mode, + :cert_store, :client_cert, :client_key, :certificate, :private_key, :verify_depth, + :version, :min_version, :max_version) + + def verify? + verify != false + end + + def disable? + !verify? + end + end + + class ProxyOptions < Options.new(:uri, :user, :password) + extend Forwardable + def_delegators :uri, :scheme, :scheme=, :host, :host=, :port, :port=, :path, :path= + + def self.from(value) + case value + when String + value = {:uri => Utils.URI(value)} + when URI + value = {:uri => value} + when Hash, Options + if uri = value.delete(:uri) + value[:uri] = Utils.URI(uri) + end + end + super(value) + end + + memoized(:user) { uri && uri.user && Utils.unescape(uri.user) } + memoized(:password) { uri && uri.password && Utils.unescape(uri.password) } + end + + class ConnectionOptions < Options.new(:request, :proxy, :ssl, :builder, :url, + :parallel_manager, :params, :headers, :builder_class) + + options :request => RequestOptions, :ssl => SSLOptions + + memoized(:request) { self.class.options_for(:request).new } + + memoized(:ssl) { self.class.options_for(:ssl).new } + + memoized(:builder_class) { RackBuilder } + + def new_builder(block) + builder_class.new(&block) + end + end + + class Env < Options.new(:method, :body, :url, :request, :request_headers, + :ssl, :parallel_manager, :params, :response, :response_headers, :status, + :reason_phrase) + + ContentLength = 'Content-Length'.freeze + StatusesWithoutBody = Set.new [204, 304] + SuccessfulStatuses = 200..299 + + # A Set of HTTP verbs that typically send a body. If no body is set for + # these requests, the Content-Length header is set to 0. + MethodsWithBodies = Set.new [:post, :put, :patch, :options] + + options :request => RequestOptions, + :request_headers => Utils::Headers, :response_headers => Utils::Headers + + extend Forwardable + + def_delegators :request, :params_encoder + + # Public + def self.from(value) + env = super(value) + if value.respond_to?(:custom_members) + env.custom_members.update(value.custom_members) + end + env + end + + # Public + def [](key) + if in_member_set?(key) + super(key) + else + custom_members[key] + end + end + + # Public + def []=(key, value) + if in_member_set?(key) + super(key, value) + else + custom_members[key] = value + end + end + + # Public + def success? + SuccessfulStatuses.include?(status) + end + + # Public + def needs_body? + !body && MethodsWithBodies.include?(method) + end + + # Public + def clear_body + request_headers[ContentLength] = '0' + self.body = '' + end + + # Public + def parse_body? + !StatusesWithoutBody.include?(status) + end + + # Public + def parallel? + !!parallel_manager + end + + def inspect + attrs = [nil] + members.each do |mem| + if value = send(mem) + attrs << "@#{mem}=#{value.inspect}" + end + end + if !custom_members.empty? + attrs << "@custom=#{custom_members.inspect}" + end + %(#<#{self.class}#{attrs.join(" ")}>) + end + + # Internal + def custom_members + @custom_members ||= {} + end + + # Internal + if members.first.is_a?(Symbol) + def in_member_set?(key) + self.class.member_set.include?(key.to_sym) + end + else + def in_member_set?(key) + self.class.member_set.include?(key.to_s) + end + end + + # Internal + def self.member_set + @member_set ||= Set.new(members) + end + end +end