lib/wash_out/param.rb in wash_out-0.1 vs lib/wash_out/param.rb in wash_out-0.2.0

- old
+ new

@@ -2,65 +2,97 @@ class Param attr_accessor :name attr_accessor :map attr_accessor :type attr_accessor :multiplied - - attr_accessor :value - def value - struct? ? map : @value - end - - def [](key) - map[key] - end - - def struct? - type == 'struct' - end - - def namespaced_type - struct? ? "typens:#{name}" : "xsd:#{type}" - end - + + # Defines a WSDL parameter with name +name+ and type specifier +type+. + # The type specifier format is described in #parse_def. def initialize(name, type, multiplied = false) type ||= {} - + @name = name.to_s @map = {} @multiplied = multiplied - if type.is_a?(Hash) + if type.is_a?(Symbol) + @type = type.to_s + else @type = 'struct' - - type.each do |name, type| - if type.is_a?(Array) - @map[name.to_s] = Param.new(name, type[0], true) - else - @map[name.to_s] = Param.new(name, type) - end + @map = self.class.parse_def(type) + end + end + + # Converts a generic externally derived Ruby value, such as String or + # Hash, to a native Ruby object according to the definition of this type. + def load(data) + if struct? + data = ActiveSupport::HashWithIndifferentAccess.new(data) + @map.map do |param| + param.load(data[param.name]) end else - @type = type.to_s + case type + when 'string'; data.to_s + when 'integer'; data.to_i + when 'double'; data.to_f + when 'boolean'; data == 'true' # Is this bad? + else raise RuntimeError, "Invalid WashOut simple type: #{type}" + end end end - - def load(data) + + # The opposite of #load. + def store(data) if struct? - map.each do |name, param| - param.load(data[name] || data[name.to_sym]) + data = ActiveSupport::HashWithIndifferentAccess.new(data) + @map.map do |param| + param.store(data[param.name]) end else - @value = Param.convert_scalar(data, type) + data.to_s end - - self end - - def self.convert_scalar(data, type) - return data.to_s if type == 'string' - return data.to_i if type == 'integer' - return data.to_f if type == 'double' - return data.to_bool if type == 'boolean' + + # Checks if this Param defines a complex type. + def struct? + type == 'struct' end + + # Returns a WSDL namespaced identifier for this type. + def namespaced_type + struct? ? "typens:#{name}" : "xsd:#{type}" + end + + # Parses a +definition+. The format of the definition is best described + # by the following BNF-like grammar. + # + # simple_type := :string | :integer | :double | :boolean + # nested_type := type_hash | simple_type | WashOut::Param instance + # type_hash := { :parameter_name => nested_type, ... } + # definition := [ WashOut::Param, ... ] | + # type_hash | + # simple_type + # + # If a simple type is passed as the +definition+, a single Param is returned + # with the +name+ set to "value". + # If a WashOut::Param instance is passed as a +nested_type+, the corresponding + # +:parameter_name+ is ignored. + # + # This function returns an array of WashOut::Param objects. + def self.parse_def(definition) + definition = { :value => definition } if definition.is_a? Symbol + + if definition.is_a? Hash + definition.map do |name, opt| + if opt.is_a? WashOut::Param + opt + else + WashOut::Param.new(name, opt) + end + end + else + definition.to_a + end + end end -end \ No newline at end of file +end