Sha256: d52797d01412d34bc58097a10c78bf3163cd90e8e65c95d661334d11dfa1998d

Contents?: true

Size: 1.52 KB

Versions: 3

Compression:

Stored size: 1.52 KB

Contents

# frozen_string_literal: true

module CottonTail
  # RouteSegment implements the pattern matching for route segments
  class RouteSegment < SimpleDelegator
    def initialize(value)
      @value = value
      super Regexp.new definition(value)
    end

    def star?
      /^#{STAR}|#{NAMED_STAR}$/.match? @value
    end

    def hash?
      /^#{HASH}|#{NAMED_HASH}$/.match? @value
    end

    def binding
      return '*' if star?

      return '#' if hash?

      @value
    end

    private

    TRANSFORM = ->(val, func) { func.call(val) }

    def definition(value)
      transformers.reduce(value, &TRANSFORM)
    end

    # Converts named route segment to Regexp named capture group
    #   "#:foo" -> "(?<foo>.+)"
    def sub_named_group_wildcard(pattern)
      pattern.gsub(NAMED_HASH, '(?<\1>.+)')
    end

    # Converts named route segment to Regexp named capture group
    #   "*:foo" -> "(?<foo>[^.]+)"
    def sub_named_single_wildcard(pattern)
      pattern.gsub(NAMED_STAR, '(?<\1>[^.]+)')
    end

    def sub_single_wildcard(pattern)
      pattern.gsub(STAR, '([^.]+)')
    end

    def sub_multi_wildcard(pattern)
      pattern.gsub(HASH, '([^.]{0,}\.?)+')
    end

    def transformers
      [
        method(:sub_named_group_wildcard),
        method(:sub_named_single_wildcard),
        method(:sub_single_wildcard),
        method(:sub_multi_wildcard)
      ]
    end

    STAR = /\*/.freeze
    HASH = /#/.freeze
    NAMED = /:(\w+)/.freeze
    NAMED_STAR = /#{STAR}#{NAMED}/.freeze
    NAMED_HASH = /#{HASH}#{NAMED}/.freeze
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
cotton-tail-0.7.0 lib/cotton_tail/route_segment.rb
cotton-tail-0.6.1 lib/cotton_tail/route_segment.rb
cotton-tail-0.6.0 lib/cotton_tail/route_segment.rb