Sha256: 51ec706ba692f919b74e218f19059f51dfbe6c66a4ca885d8a1c3abd12301958

Contents?: true

Size: 1.95 KB

Versions: 1

Compression:

Stored size: 1.95 KB

Contents

require 'simple_controller/router/route'

module SimpleController
  class Router
    class Mapper
      attr_reader :router, :namespaces, :controller_name

      def initialize(router, namespaces=[], controller_name=nil)
        @router, @namespaces, @controller_name = router, namespaces, controller_name
      end

      def namespace(namespace, &block)
        @namespaces << namespace

        mapper = self.class.new(router, namespaces, controller_name)
        mapper.instance_eval(&block)
      ensure
        @namespaces.pop
      end

      def controller(controller_name, options={}, &block)
        raise "can't have multiple controller scopes" if self.controller_name

        mapper = self.class.new(router, namespaces, controller_name)
        Array(options[:actions]).each { |action| mapper.match(action) }

        mapper.instance_eval(&block) if block_given?
      end

      def match(arg)
        route_path, partition = parse_match_arg(arg)

        route_parts = [route_path]
        route_parts.unshift(self.controller_name) if self.controller_name
        route_parts.unshift(*namespaces)

        controller_name_parts = [self.controller_name || partition.first]
        controller_name_parts.unshift(*namespaces)

        action_name = partition.last

        router.add_route join_parts(route_parts), Route.new(join_parts(controller_name_parts), action_name)
      end

      protected
      def join_parts(parts)
        parts.map do |part|
          s = part.to_s.dup
          s.chomp!("/")
          s.slice!(0) if part[0] == "/"
          s
        end.join("/")
      end

      def parse_match_arg(arg)
        if arg.class == Hash
          raise "takes only one option" unless arg.size == 1
          route_path = arg.keys.first.to_s
          partition = arg.values.first.to_s.rpartition("#")
        else
          route_path = arg.to_s
          partition = route_path.rpartition("/")
        end
        [route_path, partition]
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
simple_controller-0.1.1 lib/simple_controller/router/mapper.rb