Class URITemplate::RFC6570
In: lib/uri_template/rfc6570.rb
lib/uri_template/rfc6570/expression/named.rb
lib/uri_template/rfc6570/expression.rb
lib/uri_template/rfc6570/regex_builder.rb
Parent: Object

A uri template which should comply with the rfc 6570 ( tools.ietf.org/html/rfc6570 ). @note

  Most specs and examples refer to this class directly, because they are acutally refering to this specific implementation. If you just want uri templates, you should rather use the methods on {URITemplate} to create templates since they will select an implementation.

Methods

extract   extract_matchdata   extract_simple   level   new   to_r   tokenize!   tokens   type  

Included Modules

URITemplate

Classes and Modules

Module URITemplate::RFC6570::ClassMethods
Module URITemplate::RFC6570::Utils
Class URITemplate::RFC6570::Expression
Class URITemplate::RFC6570::Invalid
Class URITemplate::RFC6570::Literal
Class URITemplate::RFC6570::RegexBuilder
Class URITemplate::RFC6570::Token
Class URITemplate::RFC6570::Tokenizer

Constants

TYPE = :rfc6570
LITERAL = /([^"'%<>\\^`{|}\u0000-\u001F\u007F-\u009F\s]|%[0-9a-fA-F]{2})+/u   @private
                          \/ - unicode ctrl-chars
LITERAL = Regexp.compile('([^"\'%<>\\\\^`{|}\x00-\x1F\x7F-\x9F\s]|%[0-9a-fA-F]{2})+',Utils::KCODE_UTF8)   @private
CHARACTER_CLASSES = { :unreserved => { :class => '(?:[A-Za-z0-9\-\._]|%[0-9a-fA-F]{2})', :class_with_comma => '(?:[A-Za-z0-9\-\._,]|%[0-9a-fA-F]{2})', :class_without_comma => '(?:[A-Za-z0-9\-\._]|%[0-9a-fA-F]{2})', :grabs_comma => false   @private
NO_PROCESSING = []   Specifies that no processing should be done upon extraction. @see extract
CONVERT_VALUES = [:convert_values]   Specifies that the extracted values should be processed. @see extract
CONVERT_RESULT = [:convert_result]   Specifies that the extracted variable list should be processed. @see extract
DEFAULT_PROCESSING = CONVERT_VALUES + CONVERT_RESULT   Default processing. Means: convert values and the list itself. @see extract
VAR = Regexp.compile(Utils.compact_regexp(<<'__REGEXP__'), Utils::KCODE_UTF8) ( (?:[a-zA-Z0-9_]|%[0-9a-fA-F]{2}) (?:\.? (?:[a-zA-Z0-9_]|%[0-9a-fA-F]{2}) )* ) (?:(\*)|:([1-9]\d{0,3})|) __REGEXP__ ), Utils::KCODE_UTF8)   @private
EXPRESSION = Regexp.compile(Utils.compact_regexp(<<'__REGEXP__'), Utils::KCODE_UTF8) \{ ([+#\./;?&]?) ( (?:[a-zA-Z0-9_]|%[0-9a-fA-F]{2}) (?:\.?(?:[a-zA-Z0-9_]|%[0-9a-fA-F]{2}))* (?:\*|:[1-9]\d{0,3}|) (?: , (?:[a-zA-Z0-9_]|%[0-9a-fA-F]{2}) (?:\.?(?:[a-zA-Z0-9_]|%[0-9a-fA-F]{2}))* (?:\*|:[1-9]\d{0,3}|) )* ) \} __REGEXP__ ), Utils::KCODE_UTF8)   @private
URI = Regexp.compile(<<__REGEXP__.strip, Utils::KCODE_UTF8) \\A(#{LITERAL.source}|#{EXPRESSION.source})*\\z __REGEXP__ .strip, Utils::KCODE_UTF8)   @private
OPERATORS = { '' => Expression::Basic, '+' => Expression::Reserved, '#' => Expression::Fragment, '.' => Expression::Label, '/' => Expression::Path, ';' => Expression::PathParameters, '?' => Expression::FormQuery, '&' => Expression::FormQueryContinuation   @private

Attributes

options  [R] 

Public Class methods

@param pattern_or_tokens [String,Array] either a pattern as String or an Array of tokens @param options [Hash] some options @option :lazy [true,false] If true the pattern will be parsed on first access, this also means that syntax errors will not be detected unless accessed.

Public Instance methods

Extracts variables from a uri ( given as string ) or an instance of MatchData ( which was matched by the regexp of this template. The actual result depends on the value of post_processing. This argument specifies whether pair arrays should be converted to hashes.

@example Default Processing

  URITemplate::RFC6570.new('{var}').extract('value') #=> {'var'=>'value'}
  URITemplate::RFC6570.new('{&args*}').extract('&a=1&b=2') #=> {'args'=>{'a'=>'1','b'=>'2'}}
  URITemplate::RFC6570.new('{&arg,arg}').extract('&arg=1&arg=2') #=> {'arg'=>'2'}

@example No Processing

  URITemplate::RFC6570.new('{var}').extract('value', URITemplate::RFC6570::NO_PROCESSING) #=> [['var','value']]
  URITemplate::RFC6570.new('{&args*}').extract('&a=1&b=2', URITemplate::RFC6570::NO_PROCESSING) #=> [['args',[['a','1'],['b','2']]]]
  URITemplate::RFC6570.new('{&arg,arg}').extract('&arg=1&arg=2', URITemplate::RFC6570::NO_PROCESSING) #=> [['arg','1'],['arg','2']]

@raise Encoding::InvalidByteSequenceError when the given uri was not properly encoded. @raise Encoding::UndefinedConversionError when the given uri could not be converted to utf-8. @raise Encoding::CompatibilityError when the given uri could not be converted to utf-8.

@param uri_or_match [String,MatchData] Uri_or_MatchData A uri or a matchdata from which the variables should be extracted. @param post_processing [Array] Processing Specifies which processing should be done.

@note

  Don't expect that an extraction can fully recover the expanded variables. Extract rather generates a variable list which should expand to the uri from which it were extracted. In general the following equation should hold true:
    a_tpl.expand( a_tpl.extract( an_uri ) ) == an_uri

@example Extraction cruces

  two_lists = URITemplate::RFC6570.new('{listA*,listB*}')
  uri = two_lists.expand('listA'=>[1,2],'listB'=>[3,4]) #=> "1,2,3,4"
  variables = two_lists.extract( uri ) #=> {'listA'=>["1","2","3"],'listB'=>["4"]}
  # However, like said in the note:
  two_lists.expand( variables ) == uri #=> true

@note

  The current implementation drops duplicated variables instead of checking them.

Extracts variables without any proccessing. This is equivalent to {extract} with options {NO_PROCESSING}. @see extract

Returns the level of this template according to the rfc 6570 ( tools.ietf.org/html/rfc6570#section-1.2 ). Higher level means higher complexity. Basically this is defined as:

  • Level 1: no operators, one variable per expansion, no variable modifiers
  • Level 2: ’+’ and ’#’ operators, one variable per expansion, no variable modifiers
  • Level 3: all operators, multiple variables per expansion, no variable modifiers
  • Level 4: all operators, multiple variables per expansion, all variable modifiers

@example

  URITemplate::RFC6570.new('/foo/').level #=> 1
  URITemplate::RFC6570.new('/foo{bar}').level #=> 1
  URITemplate::RFC6570.new('/foo{#bar}').level #=> 2
  URITemplate::RFC6570.new('/foo{.bar}').level #=> 3
  URITemplate::RFC6570.new('/foo{bar,baz}').level #=> 3
  URITemplate::RFC6570.new('/foo{bar:20}').level #=> 4
  URITemplate::RFC6570.new('/foo{bar*}').level #=> 4

Templates of lower levels might be convertible to other formats while templates of higher levels might be incompatible. Level 1 for example should be convertible to any other format since it just contains simple expansions.

Compiles this template into a regular expression which can be used to test whether a given uri matches this template. This template is also used for {#===}.

@example

  tpl = URITemplate::RFC6570.new('/foo/{bar}/')
  regex = tpl.to_r
  regex === '/foo/baz/' #=> true
  regex === '/foz/baz/' #=> false

@return Regexp

Returns an array containing a the template tokens.

The type of this template.

@example

  tpl1 = URITemplate::RFC6570.new('/foo')
  tpl2 = URITemplate.new( tpl1.pattern, tpl1.type )
  tpl1 == tpl2 #=> true

@see {URITemplate#type}

Protected Instance methods

@private

[Validate]