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