lib/mustermann/identity.rb in mustermann-0.3.1 vs lib/mustermann/identity.rb in mustermann-0.4.0
- old
+ new
@@ -1,19 +1,75 @@
+require 'mustermann'
require 'mustermann/pattern'
+require 'mustermann/ast/node'
module Mustermann
# Matches strings that are identical to the pattern.
#
# @example
# Mustermann.new('/:foo', type: :identity) === '/bar' # => false
#
# @see Mustermann::Pattern
# @see file:README.md#identity Syntax description in the README
class Identity < Pattern
+ register :identity
+
# @param (see Mustermann::Pattern#===)
# @return (see Mustermann::Pattern#===)
# @see (see Mustermann::Pattern#===)
def ===(string)
unescape(string) == @string
+ end
+
+ # @param (see Mustermann::Pattern#peek_size)
+ # @return (see Mustermann::Pattern#peek_size)
+ # @see (see Mustermann::Pattern#peek_size)
+ def peek_size(string)
+ return unless unescape(string).start_with? @string
+ return @string.size if string.start_with? @string # optimization
+ @string.each_char.with_index.inject(0) do |count, (char, index)|
+ char_size = 1
+ escaped = @@uri.escape(char, /./)
+ char_size = escaped.size if string[index, escaped.size].downcase == escaped.downcase
+ count + char_size
+ end
+ end
+
+ # URI templates support generating templates (the logic is quite complex, though).
+ #
+ # @example (see Mustermann::Pattern#to_templates)
+ # @param (see Mustermann::Pattern#to_templates)
+ # @return (see Mustermann::Pattern#to_templates)
+ # @see Mustermann::Pattern#to_templates
+ def to_templates
+ [@@uri.escape(to_s)]
+ end
+
+ # Generates an AST so it's compatible with {Mustermann::AST::Pattern}.
+ # Not used internally by {Mustermann::Identity}.
+ # @!visibility private
+ def to_ast
+ payload = @string.each_char.with_index.map { |c, i| AST::Node[c == ?/ ? :separator : :char].new(c, start: i, stop: i+1) }
+ AST::Node[:root].new(payload, pattern: @string, start: 0, stop: @string.length)
+ end
+
+ # Identity patterns support expanding.
+ #
+ # This implementation does not use {Mustermann::Expander} internally to save memory and
+ # compilation time.
+ #
+ # @example (see Mustermann::Pattern#expand)
+ # @param (see Mustermann::Pattern#expand)
+ # @return (see Mustermann::Pattern#expand)
+ # @raise (see Mustermann::Pattern#expand)
+ # @see Mustermann::Pattern#expand
+ # @see Mustermann::Expander
+ def expand(behavior = nil, values = {})
+ return to_s if values.empty? or behavior == :ignore
+ raise ExpandError, "cannot expand with keys %p" % values.keys.sort if behavior == :raise
+ raise ArgumentError, "unknown behavior %p" % behavior if behavior != :append
+ params = values.map { |key, value| @@uri.escape(key.to_s) + "=" + @@uri.escape(value.to_s, /[^\w]/) }
+ separator = @string.include?(??) ? ?& : ??
+ @string + separator + params.join(?&)
end
end
end