lib/mustermann/expander.rb in mustermann-0.2.0 vs lib/mustermann/expander.rb in mustermann-0.3.0
- old
+ new
@@ -91,11 +91,11 @@
# @example casting all ActiveRecord objects to param
# expander.cast(ActiveRecord::Base, &:to_param)
#
# @param [Array<Symbol, Regexp, #===>] type_matchers
# To identify key/value pairs to match against.
- # Regexps and Symbols match againg key, everything else matches against value.
+ # Regexps and Symbols match against key, everything else matches against value.
#
# @yield every key/value pair
# @yieldparam key [Symbol] omitted if block takes less than 2
# @yieldparam value [Object] omitted if block takes no arguments
# @yieldreturn [Hash{Symbol: Object}] will replace key/value pair with returned hash
@@ -136,24 +136,53 @@
#
# @return [String] expanded string
# @raise [NotImplementedError] raised if expand is not supported.
# @raise [Mustermann::ExpandError] raised if a value is missing or unknown
def expand(behavior = nil, **values)
- values = caster.cast(values)
+ behavior, values = nil, behavior if behavior.is_a? Hash
+ values = map_values(values)
case behavior || additional_values
when :raise then @api_expander.expand(values)
when :ignore then with_rest(values) { |uri, rest| uri }
when :append then with_rest(values) { |uri, rest| append(uri, rest) }
else raise ArgumentError, "unknown behavior %p" % behavior
end
end
+ # @see Object#==
+ def ==(other)
+ return false unless other.class == self.class
+ other.patterns == patterns and other.additional_values == additional_values
+ end
+
+ # @see Object#eql?
+ def eql?(other)
+ return false unless other.class == self.class
+ other.patterns.eql? patterns and other.additional_values.eql? additional_values
+ end
+
+ # @see Object#hash
+ def hash
+ patterns.hash + additional_values.hash
+ end
+
+ def expandable?(values)
+ return false unless values
+ expandable, _ = split_values(map_values(values))
+ @api_expander.expandable? expandable
+ end
+
def with_rest(values)
+ expandable, non_expandable = split_values(values)
+ yield expand(:raise, slice(values, expandable)), slice(values, non_expandable)
+ end
+
+ def split_values(values)
expandable = @api_expander.expandable_keys(values.keys)
non_expandable = values.keys - expandable
- yield expand(:raise, slice(values, expandable)), slice(values, non_expandable)
+ [expandable, non_expandable]
end
def slice(hash, keys)
Hash[keys.map { |k| [k, hash[k]] }]
end
@@ -162,8 +191,14 @@
return uri unless values and values.any?
entries = values.map { |pair| pair.map { |e| @api_expander.escape(e, also_escape: /[\/\?#\&\=%]/) }.join(?=) }
"#{ uri }#{ uri[??]??&:?? }#{ entries.join(?&) }"
end
- private :with_rest, :slice, :append, :caster
+ def map_values(values)
+ values = values.dup
+ @api_expander.keys.each { |key| values[key] ||= values.delete(key.to_s) if values.include? key.to_s }
+ caster.cast(values)
+ end
+
+ private :with_rest, :slice, :append, :caster, :map_values, :split_values
end
end