Class: ActionWebService::Casting::BaseCaster
- Inherits:
-
Object
- Object
- 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:
13 14 15 |
# File 'lib/action_web_service/casting.rb', line 13 def initialize(api_method) @api_method = api_method end |
Class Method Details
.cast(value, signature_type) ⇒ Object
:nodoc:
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/action_web_service/casting.rb', line 46 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.simple? return value 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:
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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/action_web_service/casting.rb', line 73 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 if value.kind_of?(Hash) value = "%s/%s/%s %s:%s:%s" % value.values_at(*%w[2 3 1 4 5 6]) Time.respond_to?(:strptime) ? Time.strptime(value.to_s, "%m/%d/%Y %H:%M:%S") : Time.parse(value.to_s) elsif value.kind_of?(Time) value elsif value.kind_of?(DateTime) value.to_time else Time.parse(value.to_s) end when :date if value.kind_of?(Hash) value = "%s/%s/%s" % value.values_at(*%w[2 3 1]) return Date.strptime(value.to_s,"%m/%d/%Y") end value.kind_of?(Date) ? value : Date.parse(value.to_s) when :datetime if value.kind_of?(Hash) value = "%s/%s/%s %s:%s:%s" % value.values_at(*%w[2 3 1 4 5 6]) return DateTime.strptime(value.to_s,"%m/%d/%Y %H:%M:%S") end value.kind_of?(DateTime) ? value : DateTime.parse(value.to_s) end end |
.cast_expects(api_method, params) ⇒ Object
:nodoc:
32 33 34 35 36 37 38 39 |
# File 'lib/action_web_service/casting.rb', line 32 def cast_expects(api_method, params) # :nodoc: return [] if api_method.expects.nil? if params.is_a?(Array) api_method.expects.zip(params).map{ |type, param| cast(param, type) } elsif params.is_a?(Hash) api_method.expects.map {|type| cast(params[type.name.to_s], type) } end end |
.cast_returns(api_method, return_value) ⇒ Object
:nodoc:
41 42 43 44 |
# File 'lib/action_web_service/casting.rb', line 41 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:
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/action_web_service/casting.rb', line 133 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
19 20 21 |
# File 'lib/action_web_service/casting.rb', line 19 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
25 26 27 |
# File 'lib/action_web_service/casting.rb', line 25 def cast_returns(return_value) self.class.cast_returns(@api_method, return_value) end |