Class: Addressable::Template
- Inherits:
-
Object
- Object
- Addressable::Template
- Defined in:
- lib/addressable/template.rb
Overview
This is an implementation of a URI template based on RFC 6570 (tools.ietf.org/html/rfc6570).
Defined Under Namespace
Classes: InvalidTemplateOperatorError, InvalidTemplateValueError, MatchData, TemplateOperatorAbortedError
Constant Summary collapse
- RESERVED =
"(?:[#{anything}]|%[a-fA-F0-9][a-fA-F0-9])"
- UNRESERVED =
"(?:[#{ Addressable::URI::CharacterClasses::UNRESERVED }]|%[a-fA-F0-9][a-fA-F0-9])"
- VARNAME =
/^#{variable}$/
- VARSPEC =
/^#{varspec}$/
- VARIABLE_LIST =
/^#{varspec}(?:,#{varspec})*$/
- EXPRESSION =
/\{([#{operator}])?(#{varspec}(?:,#{varspec})*)\}/
- LEADERS =
{ '?' => '?', '/' => '/', '#' => '#', '.' => '.', ';' => ';', '&' => '&' }
- JOINERS =
{ '?' => '&', '.' => '.', ';' => ';', '&' => '&', '/' => '/' }
Instance Attribute Summary collapse
-
#pattern ⇒ String
readonly
The Template object’s pattern.
Instance Method Summary collapse
-
#==(template) ⇒ TrueClass, FalseClass
(also: #eql?)
Returns
true
if the Template objects are equal. -
#expand(mapping, processor = nil, normalize_values = true) ⇒ Addressable::URI
Expands a URI template into a full URI.
-
#extract(uri, processor = nil) ⇒ Hash, NilClass
Extracts a mapping from the URI using a URI Template pattern.
-
#freeze ⇒ Addressable::URI
Freeze URI, initializing instance variables.
-
#initialize(pattern) ⇒ Addressable::Template
constructor
Creates a new
Addressable::Template
object. -
#inspect ⇒ String
Returns a
String
representation of the Template object’s state. -
#match(uri, processor = nil) ⇒ Hash, NilClass
Extracts match data from the URI using a URI Template pattern.
-
#named_captures ⇒ Hash
private
Returns the named captures of the coerced ‘Regexp`.
-
#partial_expand(mapping, processor = nil, normalize_values = true) ⇒ Addressable::Template
Expands a URI template into another URI template.
-
#source ⇒ String
private
Returns the source of the coerced ‘Regexp`.
-
#to_regexp ⇒ Regexp
Coerces a template into a ‘Regexp` object.
-
#variable_defaults ⇒ Hash
Returns a mapping of variables to their default values specified in the template.
-
#variables ⇒ Array
(also: #keys, #names)
Returns an Array of variables used within the template pattern.
Constructor Details
#initialize(pattern) ⇒ Addressable::Template
Creates a new Addressable::Template
object.
235 236 237 238 239 240 |
# File 'lib/addressable/template.rb', line 235 def initialize(pattern) if !pattern.respond_to?(:to_str) raise TypeError, "Can't convert #{pattern.class} into String." end @pattern = pattern.to_str.dup.freeze end |
Instance Attribute Details
#pattern ⇒ String (readonly)
Returns The Template object’s pattern.
255 256 257 |
# File 'lib/addressable/template.rb', line 255 def pattern @pattern end |
Instance Method Details
#==(template) ⇒ TrueClass, FalseClass Also known as: eql?
Returns true
if the Template objects are equal. This method does NOT normalize either Template before doing the comparison.
275 276 277 278 |
# File 'lib/addressable/template.rb', line 275 def ==(template) return false unless template.kind_of?(Template) return self.pattern == template.pattern end |
#expand(mapping, processor = nil, normalize_values = true) ⇒ Addressable::URI
Expands a URI template into a full URI.
The object should respond to either the validate
or transform
messages or both. Both the validate
and transform
methods should take two parameters: name
and value
. The validate
method should return true
or false
; true
if the value of the variable is valid, false
otherwise. An InvalidTemplateValueError
exception will be raised if the value is invalid. The transform
method should return the transformed variable value as a String
. If a transform
method is used, the value will not be percent encoded automatically. Unicode normalization will be performed both before and after sending the value to the transform method.
592 593 594 595 596 597 598 599 |
# File 'lib/addressable/template.rb', line 592 def (mapping, processor=nil, normalize_values=true) result = self.pattern.dup mapping = normalize_keys(mapping) result.gsub!( EXPRESSION ) do |capture| transform_capture(mapping, capture, processor, normalize_values) end return Addressable::URI.parse(result) end |
#extract(uri, processor = nil) ⇒ Hash, NilClass
Extracts a mapping from the URI using a URI Template pattern.
343 344 345 346 |
# File 'lib/addressable/template.rb', line 343 def extract(uri, processor=nil) match_data = self.match(uri, processor) return (match_data ? match_data.mapping : nil) end |
#freeze ⇒ Addressable::URI
Freeze URI, initializing instance variables.
246 247 248 249 250 251 |
# File 'lib/addressable/template.rb', line 246 def freeze self.variables self.variable_defaults self.named_captures super end |
#inspect ⇒ String
Returns a String
representation of the Template object’s state.
261 262 263 264 |
# File 'lib/addressable/template.rb', line 261 def inspect sprintf("#<%s:%#0x PATTERN:%s>", self.class.to_s, self.object_id, self.pattern) end |
#match(uri, processor = nil) ⇒ Hash, NilClass
Extracts match data from the URI using a URI Template pattern.
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 |
# File 'lib/addressable/template.rb', line 414 def match(uri, processor=nil) uri = Addressable::URI.parse(uri) unless uri.is_a?(Addressable::URI) mapping = {} # First, we need to process the pattern, and extract the values. expansions, expansion_regexp = parse_template_pattern(pattern, processor) return nil unless uri.to_str.match(expansion_regexp) unparsed_values = uri.to_str.scan(expansion_regexp).flatten if uri.to_str == pattern return Addressable::Template::MatchData.new(uri, self, mapping) elsif expansions.size > 0 index = 0 expansions.each do |expansion| _, operator, varlist = *expansion.match(EXPRESSION) varlist.split(',').each do |varspec| _, name, modifier = *varspec.match(VARSPEC) mapping[name] ||= nil case operator when nil, '+', '#', '/', '.' unparsed_value = unparsed_values[index] name = varspec[VARSPEC, 1] value = unparsed_value value = value.split(JOINERS[operator]) if value && modifier == '*' when ';', '?', '&' if modifier == '*' if unparsed_values[index] value = unparsed_values[index].split(JOINERS[operator]) value = value.inject({}) do |acc, v| key, val = v.split('=') val = "" if val.nil? acc[key] = val acc end end else if (unparsed_values[index]) name, value = unparsed_values[index].split('=') value = "" if value.nil? end end end if processor != nil && processor.respond_to?(:restore) value = processor.restore(name, value) end if processor == nil if value.is_a?(Hash) value = value.inject({}){|acc, (k, v)| acc[Addressable::URI.unencode_component(k)] = Addressable::URI.unencode_component(v) acc } elsif value.is_a?(Array) value = value.map{|v| Addressable::URI.unencode_component(v) } else value = Addressable::URI.unencode_component(value) end end if !mapping.has_key?(name) || mapping[name].nil? # Doesn't exist, set to value (even if value is nil) mapping[name] = value end index = index + 1 end end return Addressable::Template::MatchData.new(uri, self, mapping) else return nil end end |
#named_captures ⇒ Hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the named captures of the coerced ‘Regexp`.
652 653 654 |
# File 'lib/addressable/template.rb', line 652 def named_captures self.to_regexp.named_captures end |
#partial_expand(mapping, processor = nil, normalize_values = true) ⇒ Addressable::Template
Expands a URI template into another URI template.
The object should respond to either the validate
or transform
messages or both. Both the validate
and transform
methods should take two parameters: name
and value
. The validate
method should return true
or false
; true
if the value of the variable is valid, false
otherwise. An InvalidTemplateValueError
exception will be raised if the value is invalid. The transform
method should return the transformed variable value as a String
. If a transform
method is used, the value will not be percent encoded automatically. Unicode normalization will be performed both before and after sending the value to the transform method.
525 526 527 528 529 530 531 532 |
# File 'lib/addressable/template.rb', line 525 def (mapping, processor=nil, normalize_values=true) result = self.pattern.dup mapping = normalize_keys(mapping) result.gsub!( EXPRESSION ) do |capture| transform_partial_capture(mapping, capture, processor, normalize_values) end return Addressable::Template.new(result) end |
#source ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the source of the coerced ‘Regexp`.
642 643 644 |
# File 'lib/addressable/template.rb', line 642 def source self.to_regexp.source end |
#to_regexp ⇒ Regexp
Coerces a template into a ‘Regexp` object. This regular expression will behave very similarly to the actual template, and should match the same URI values, but it cannot fully handle, for example, values that would extract to an `Array`.
631 632 633 634 |
# File 'lib/addressable/template.rb', line 631 def to_regexp _, source = parse_template_pattern(pattern) Regexp.new(source) end |
#variable_defaults ⇒ Hash
Returns a mapping of variables to their default values specified in the template. Variables without defaults are not returned.
619 620 621 622 |
# File 'lib/addressable/template.rb', line 619 def variable_defaults @variable_defaults ||= Hash[*ordered_variable_defaults.reject { |k, v| v.nil? }.flatten] end |
#variables ⇒ Array Also known as: keys, names
Returns an Array of variables used within the template pattern. The variables are listed in the Array in the order they appear within the pattern. Multiple occurrences of a variable within a pattern are not represented in this Array.
608 609 610 |
# File 'lib/addressable/template.rb', line 608 def variables @variables ||= ordered_variable_defaults.map { |var, val| var }.uniq end |