plainrouter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0ab4ab8ebf9af90ff699545a92ee7d7cd33a6bfd
4
+ data.tar.gz: ad2625b74ee5727626a9850125ebe8731e274e5a
5
+ SHA512:
6
+ metadata.gz: 43533f0431467f5b57e318a4e58de660f65c9ad523e349bdde529e79392c45d7f3c401977c14816eeb47e04aa84d2e1c271816b9f90d9a12c19b54271a5b390b
7
+ data.tar.gz: 057e5030240a0d17a49ded2b289e9d6e753e9a8ff720dd3a5d7ace1382f360254cd2544e5041d31bda1e73add7e50416bab79169f869d6ba17933e0354113998
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.4
4
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in plainrouter.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Yusuke Wada
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,99 @@
1
+ # PlainRouter
2
+
3
+ [![Build Status](https://travis-ci.org/yusukebe/plainrouter.svg?branch=master)](https://travis-ci.org/yusukebe/plainrouter)
4
+
5
+ PlainRouter is a **fast** and **simple** routing engine for Ruby. Using `PlainRouter::Method`, you can quickly make web application framework like Sinatra. PlainRouter is a porting project of [Route::Boom](https://metacpan.org/pod/Router::Boom).
6
+
7
+ ## Install
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```
12
+ gem 'plainrouter'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ ```
18
+ $ bundle
19
+ ```
20
+
21
+ Or install it yourself as:
22
+
23
+ ```
24
+ $ gem install plainrouter
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ Here is synopsis of using **PlainRouter**
30
+
31
+ ```ruby
32
+ router = PlainRouter.new
33
+ router.add('/', 'dispatch_root')
34
+ router.add('/entries', 'dispatch_entries')
35
+ router.add('/entries/:id', 'dispatch_permalink')
36
+ router.add('/users/:user/{year}', 'dispatch_year')
37
+ router.add('/users/:user/{year}/{month:\d+}', 'dispatch_month')
38
+
39
+ dest, captured = router.match(env['PATH_INFO'])
40
+ ```
41
+
42
+ **PlainRouter::Method** supports HTTP methods. Sinatra-like Web Framework and Application are below
43
+
44
+ ```ruby
45
+ class SinatraLikeFramework
46
+ def initialize
47
+ @router = PlainRouter::Method.new
48
+ self.routes
49
+ end
50
+ def routes
51
+ end
52
+ def get(path, &block)
53
+ @router.add('GET', path, block)
54
+ end
55
+ def call(env)
56
+ block, params = @router.match(env['REQUEST_METHOD'], env['PATH_INFO'])
57
+ unless block.instance_of?(Proc)
58
+ return not_found
59
+ end
60
+ response = block.call(params)
61
+ if response.instance_of?(Array)
62
+ return response
63
+ elsif response.instance_of?(String)
64
+ return [200, {"Content-Type" => "text/plain"}, [res]]
65
+ end
66
+ not_found
67
+ end
68
+ def not_found
69
+ [404, {"Content-Type" => "text/plain"}, ['Not Found']]
70
+ end
71
+ end
72
+
73
+ class SinatraLikeApplication < SinatraLikeFramework
74
+ def routes
75
+ get '/' do
76
+ 'Hello World!'
77
+ end
78
+ get '/user/:name' do |params|
79
+ "Hello #{params['name']}!"
80
+ end
81
+ end
82
+ end
83
+
84
+ run SinatraLikeApplication.new
85
+ ```
86
+
87
+ ## License
88
+
89
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
90
+
91
+ ## See Also
92
+
93
+ * [Rooter::Boom](https://metacpan.org/pod/Router::Boom)
94
+ * [rack-router](https://github.com/pjb3/rack-router)
95
+
96
+ ## Author
97
+
98
+ Yusuke Wada <https://github.com/yusukebe>
99
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "plainrouter"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,44 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'plainrouter/method'
3
+ require 'rack'
4
+
5
+ class SinatraLikeFramework
6
+ def initialize
7
+ @router = PlainRouter::Method.new
8
+ self.routes
9
+ end
10
+ def routes
11
+ end
12
+ def get(path, &block)
13
+ @router.add('GET', path, block)
14
+ end
15
+ def call(env)
16
+ block, params = @router.match(env['REQUEST_METHOD'], env['PATH_INFO'])
17
+ unless block.instance_of?(Proc)
18
+ return not_found
19
+ end
20
+ response = block.call(params)
21
+ if response.instance_of?(Array)
22
+ return response
23
+ elsif response.instance_of?(String)
24
+ return [200, {"Content-Type" => "text/plain"}, [res]]
25
+ end
26
+ not_found
27
+ end
28
+ def not_found
29
+ [404, {"Content-Type" => "text/plain"}, ['Not Found']]
30
+ end
31
+ end
32
+
33
+ class SinatraLikeApplication < SinatraLikeFramework
34
+ def routes
35
+ get '/' do
36
+ 'Hello World!'
37
+ end
38
+ get '/user/:name' do |params|
39
+ "Hello #{params['name']}!"
40
+ end
41
+ end
42
+ end
43
+
44
+ run SinatraLikeApplication.new
@@ -0,0 +1,68 @@
1
+ require "plainrouter/version"
2
+
3
+ class PlainRouter
4
+ def initialize
5
+ @routes = []
6
+ @compiled_regexp
7
+ end
8
+
9
+ def add(path_info, stuff)
10
+ nodes, captures = [], []
11
+ regexp = Regexp.union(/{((?:\{[0-9,]+\}|[^{}]+)+)}/,
12
+ /:([A-Za-z0-9_]+)/,
13
+ /(\*)/,
14
+ /([^{:*]+)/)
15
+ path_info.sub(/(^\/)/,'').split('/').each.with_index do |path, pos|
16
+ match = {position: nil, value: nil}
17
+ path.match(regexp).size.times do |index|
18
+ last_match = Regexp.last_match(index)
19
+ if last_match
20
+ match[:value] = last_match
21
+ match[:position] = index
22
+ end
23
+ end
24
+ case match[:position]
25
+ when 1 then
26
+ captures[pos], pattern = match[:value].split(':')
27
+ pattern = pattern ? "(#{pattern})" : "([^/]+)"
28
+ nodes.push(pattern)
29
+ when 2 then
30
+ captures[pos] = match[:value]
31
+ nodes.push("([^/]+)")
32
+ when 3 then
33
+ captures[pos] = '*'
34
+ nodes.push("(.+)")
35
+ else
36
+ nodes.push(path)
37
+ end
38
+ end
39
+ @routes.push({path: '/' + nodes.join('/'), stuff: stuff, captures: captures })
40
+ self.compile
41
+ end
42
+
43
+ def compile
44
+ regexps = @routes.map.with_index {|r, index| /(?<_#{index}>#{r[:path]})/}
45
+ @compiled_regexp = /\A#{Regexp.union(regexps)}\z/
46
+ end
47
+
48
+ def match(path_info)
49
+ return if @compiled_regexp.nil?
50
+ match = path_info.match(@compiled_regexp)
51
+ @routes.size.times do |i|
52
+ if Regexp.last_match("_#{i}")
53
+ response = {}
54
+ stuff = @routes[i][:stuff]
55
+ captures = @routes[i][:captures]
56
+ path_info.gsub(/([^\/]+)/).with_index do |path, pos|
57
+ response[captures[pos]] = path if captures[pos] != nil
58
+ end
59
+ if response.empty?
60
+ return stuff
61
+ else
62
+ return stuff, response
63
+ end
64
+ end
65
+ end
66
+ return
67
+ end
68
+ end
@@ -0,0 +1,54 @@
1
+ require "plainrouter"
2
+
3
+ class PlainRouter::Method
4
+ def initialize
5
+ @router
6
+ @data = {}
7
+ @path = []
8
+ @path_seen = {}
9
+ end
10
+
11
+ def add(methods, path, opaque = nil)
12
+ router = nil
13
+ if @path_seen[path].nil?
14
+ @path.push(path)
15
+ @path_seen[path] = true
16
+ end
17
+ @data[path] ||= []
18
+ methods = [methods] unless methods.instance_of?(Array)
19
+ methods.each do |method|
20
+ @data[path].push([method, opaque])
21
+ end
22
+ end
23
+
24
+ def match(request_method, path)
25
+ router ||= self.build_router
26
+ if response = router.match(path)
27
+ patterns, captured = nil, nil
28
+ if response.last.instance_of?(Array)
29
+ patterns = response
30
+ else
31
+ patterns = response[0]
32
+ captured = response[1]
33
+ end
34
+ patterns.each do |pattern|
35
+ if pattern[0].nil? || request_method == pattern[0]
36
+ if captured.nil?
37
+ return pattern[1]
38
+ else
39
+ return pattern[1], captured
40
+ end
41
+ end
42
+ end
43
+ end
44
+ return
45
+ end
46
+
47
+ def build_router
48
+ router = PlainRouter.new
49
+ @path.each do |path|
50
+ router.add(path, @data[path])
51
+ end
52
+ return router
53
+ end
54
+ end
@@ -0,0 +1,3 @@
1
+ class PlainRouter
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'plainrouter/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "plainrouter"
8
+ spec.version = PlainRouter::VERSION
9
+ spec.authors = ["Yusuke Wada"]
10
+ spec.email = ["yusuke@kamawada.com"]
11
+
12
+ spec.summary = %q{Fast and simple routing engine for Ruby}
13
+ spec.description = %q{PlainRouter is a fast and simple routing engine for Ruby. Using PlainRouter::Method, you can quickly make web application framework like Sinatra. PlainRouter is a porting project of Route::Boom.}
14
+ spec.homepage = "https://github.com/yusukebe/plainrouter"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.11"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "rspec", "~> 3.0"
25
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: plainrouter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Yusuke Wada
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-04-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: PlainRouter is a fast and simple routing engine for Ruby. Using PlainRouter::Method,
56
+ you can quickly make web application framework like Sinatra. PlainRouter is a porting
57
+ project of Route::Boom.
58
+ email:
59
+ - yusuke@kamawada.com
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - ".gitignore"
65
+ - ".rspec"
66
+ - ".travis.yml"
67
+ - Gemfile
68
+ - LICENSE.txt
69
+ - README.md
70
+ - Rakefile
71
+ - bin/console
72
+ - bin/setup
73
+ - example/sinatra_like.ru
74
+ - lib/plainrouter.rb
75
+ - lib/plainrouter/method.rb
76
+ - lib/plainrouter/version.rb
77
+ - plainrouter.gemspec
78
+ homepage: https://github.com/yusukebe/plainrouter
79
+ licenses:
80
+ - MIT
81
+ metadata: {}
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 2.4.5.1
99
+ signing_key:
100
+ specification_version: 4
101
+ summary: Fast and simple routing engine for Ruby
102
+ test_files: []