Class: ActionWebService::Casting::BaseCaster
- Extended by:
- SignatureTypes
- Defined in:
- lib/action_web_service/casting.rb
Overview
Performs casting of arbitrary values into the correct types for the signature
Class Method Summary collapse
-
.cast(value, signature_type) ⇒ Object
:nodoc:.
-
.cast_base_type(value, signature_type) ⇒ Object
:nodoc:.
-
.cast_expects(api_method, params) ⇒ Object
:nodoc:.
-
.cast_returns(api_method, return_value) ⇒ Object
:nodoc:.
-
.cast_to_structured_type(value, signature_type) ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#cast_expects(params) ⇒ Object
Coerces the parameters in
params
(an Enumerable) into the types this method expects. -
#cast_returns(return_value) ⇒ Object
Coerces the given
return_value
into the type returned by this method. -
#initialize(api_method) ⇒ BaseCaster
constructor
:nodoc:.
Methods included from SignatureTypes
canonical_signature, canonical_signature_entry, canonical_type, canonical_type_class, canonical_type_name, class_to_type_name, derived_from?, symbol_name, type_name_to_class
Constructor Details
#initialize(api_method) ⇒ BaseCaster
:nodoc:
12 13 14 |
# File 'lib/action_web_service/casting.rb', line 12 def initialize(api_method) @api_method = api_method end |
Class Method Details
.cast(value, signature_type) ⇒ Object
:nodoc:
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/action_web_service/casting.rb', line 41 def cast(value, signature_type) # :nodoc: return value if signature_type.nil? # signature.length != params.length return nil if value.nil? # XMLRPC protocol doesn't support nil values. It uses false instead. # It should never happen for SOAP. if signature_type.structured? && value.equal?(false) return nil end unless signature_type.array? || signature_type.structured? return value if canonical_type(value.class) == signature_type.type end if signature_type.array? unless value.respond_to?(:entries) && !value.is_a?(String) raise CastingError, "Don't know how to cast #{value.class} into #{signature_type.type.inspect}" end value.entries.map do |entry| cast(entry, signature_type.element_type) end elsif signature_type.structured? cast_to_structured_type(value, signature_type) elsif !signature_type.custom? cast_base_type(value, signature_type) end end |
.cast_base_type(value, signature_type) ⇒ Object
:nodoc:
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/action_web_service/casting.rb', line 66 def cast_base_type(value, signature_type) # :nodoc: # This is a work-around for the fact that XML-RPC special-cases DateTime values into its own DateTime type # in order to support iso8601 dates. This doesn't work too well for us, so we'll convert it into a Time, # with the caveat that we won't be able to handle pre-1970 dates that are sent to us. # # See http://dev.rubyonrails.com/ticket/2516 value = value.to_time if value.is_a?(XMLRPC::DateTime) case signature_type.type when :int Integer(value) when :string value.to_s when :base64 if value.is_a?(ActionWebService::Base64) value else ActionWebService::Base64.new(value.to_s) end when :bool return false if value.nil? return value if value == true || value == false case value.to_s.downcase when '1', 'true', 'y', 'yes' true when '0', 'false', 'n', 'no' false else raise CastingError, "Don't know how to cast #{value.class} into Boolean" end when :float Float(value) when :decimal BigDecimal(value.to_s) when :time value = "%s/%s/%s %s:%s:%s" % value.values_at(*%w[2 3 1 4 5 6]) if value.kind_of?(Hash) if value.kind_of?(Time) value elsif value.kind_of?(DateTime) value.to_time else Time.parse(value.to_s) end when :date value = "%s/%s/%s" % value.values_at(*%w[2 3 1]) if value.kind_of?(Hash) value.kind_of?(Date) ? value : Date.parse(value.to_s) when :datetime value = "%s/%s/%s %s:%s:%s" % value.values_at(*%w[2 3 1 4 5 6]) if value.kind_of?(Hash) value.kind_of?(DateTime) ? value : DateTime.parse(value.to_s) end end |
.cast_expects(api_method, params) ⇒ Object
:nodoc:
31 32 33 34 |
# File 'lib/action_web_service/casting.rb', line 31 def cast_expects(api_method, params) # :nodoc: return [] if api_method.expects.nil? api_method.expects.zip(params).map{ |type, param| cast(param, type) } end |
.cast_returns(api_method, return_value) ⇒ Object
:nodoc:
36 37 38 39 |
# File 'lib/action_web_service/casting.rb', line 36 def cast_returns(api_method, return_value) # :nodoc: return nil if api_method.returns.nil? cast(return_value, api_method.returns[0]) end |
.cast_to_structured_type(value, signature_type) ⇒ Object
:nodoc:
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/action_web_service/casting.rb', line 118 def cast_to_structured_type(value, signature_type) # :nodoc: obj = nil # if the canonical classes are the same or if the given value is of # a type that is derived from the signature_type do not attempt to # "cast" the value into the signature_type as it's already good to go obj = ( canonical_type(value.class) == canonical_type(signature_type.type) or derived_from?(signature_type.type, value.class) ) ? value : signature_type.type_class.new if value.respond_to?(:each_pair) klass = signature_type.type_class value.each_pair do |name, val| type = klass.respond_to?(:member_type) ? klass.member_type(name) : nil val = cast(val, type) if type # See http://dev.rubyonrails.com/ticket/3567 val = val.to_time if val.is_a?(XMLRPC::DateTime) obj.__send__("#{name}=", val) if obj.respond_to?(name) end elsif value.respond_to?(:attributes) signature_type.each_member do |name, type| val = value.__send__(name) obj.__send__("#{name}=", cast(val, type)) if obj.respond_to?(name) end else raise CastingError, "Don't know how to cast #{value.class} to #{signature_type.type_class}" end obj end |
Instance Method Details
#cast_expects(params) ⇒ Object
Coerces the parameters in params
(an Enumerable) into the types this method expects
18 19 20 |
# File 'lib/action_web_service/casting.rb', line 18 def cast_expects(params) self.class.cast_expects(@api_method, params) end |
#cast_returns(return_value) ⇒ Object
Coerces the given return_value
into the type returned by this method
24 25 26 |
# File 'lib/action_web_service/casting.rb', line 24 def cast_returns(return_value) self.class.cast_returns(@api_method, return_value) end |