rack-way 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 016cf1e2d4ae57cf31b359733bf96c3510667bc9de887322c18a2118dcb54ba9
4
+ data.tar.gz: b491da7388431e3d6b07a7b904af1d5d6b732b510c44904a0c93cd26978f0b07
5
+ SHA512:
6
+ metadata.gz: c5948a9e5366dab3e86832df6f5fc66a9c837320689c3c6a2507c8f7b7a7c080272388159f44d464e07ba6ec1541377e9021ba83b33cb91958d0ff8005ba35de
7
+ data.tar.gz: 1694ea321074055bdf57518e8dd6c16cf634b732c87561c4edd2f0a64af0c6ec714373acbfd9bdc59b6459ed9231a4c31f036b0151533aaaf26001ab79f9b538
data/lib/rack-way.rb ADDED
@@ -0,0 +1,53 @@
1
+ require 'rack-way/router'
2
+ require 'rack-way/action'
3
+
4
+ module Rack
5
+ class Way
6
+ include Action
7
+
8
+ def initialize
9
+ @router = Router.new
10
+ end
11
+
12
+ def draw_app(&block)
13
+ instance_eval(&block)
14
+
15
+ @router
16
+ end
17
+
18
+ def namespace(name, &block)
19
+ @router.append_namespace(name)
20
+ instance_eval(&block)
21
+
22
+ @router.clear_last_namespace
23
+ end
24
+
25
+ def root(endpoint)
26
+ @router.add('GET', '', endpoint)
27
+ end
28
+
29
+ def not_found(endpoint)
30
+ @router.add_not_found(endpoint)
31
+ end
32
+
33
+ def get(path, endpoint)
34
+ @router.add('GET', path, endpoint)
35
+ end
36
+
37
+ def post(path, endpoint)
38
+ @router.add('POST', path, endpoint)
39
+ end
40
+
41
+ def delete(path, endpoint)
42
+ @router.add('DELETE', path, endpoint)
43
+ end
44
+
45
+ def put(path, endpoint)
46
+ @router.add('PUT', path, endpoint)
47
+ end
48
+
49
+ def patch(path, endpoint)
50
+ @router.add('PATCH', path, endpoint)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,60 @@
1
+ require 'erubis'
2
+ require 'json'
3
+ require 'rack'
4
+
5
+ module Rack
6
+ class Way
7
+ module Action
8
+ def render(content, headers: {"Content-Type" => "text/html"}, status: 200)
9
+ Rack::Way::Action.render(content, headers: headers, status: status)
10
+ end
11
+
12
+ def render_erb(path, params = {}, status: 200)
13
+ Rack::Way::Action.render_erb(path, params, status: status)
14
+ end
15
+
16
+ def render_json(content = {}, status: 200)
17
+ Rack::Way::Action.render_json(content, status: status)
18
+ end
19
+
20
+ def erb(path, params = {})
21
+ Rack::Way::Action.erb(path, params)
22
+ end
23
+
24
+ def redirect_to(url)
25
+ Rack::Way::Action.redirect_to(url)
26
+ end
27
+
28
+ class << self
29
+ def render(content, headers: {"Content-Type" => "text/html"}, status: 200)
30
+ [status, headers, [content]]
31
+ end
32
+
33
+ def render_erb(paths, params = {}, status: 200)
34
+ if paths.kind_of?(Array)
35
+ erb =
36
+ paths.map { |path| erb(path, params) }.join
37
+ else
38
+ erb = erb(paths, params)
39
+ end
40
+
41
+ [status, {"Content-Type" => "text/html"}, [erb]]
42
+ end
43
+
44
+ def render_json(content = {}, status: 200)
45
+ [status, {"Content-Type" => "application/json"}, [content.to_json]]
46
+ end
47
+
48
+ def erb(path, params = {})
49
+ Erubis::FastEruby
50
+ .load_file("#{path}.html.erb")
51
+ .result(params)
52
+ end
53
+
54
+ def redirect_to(url)
55
+ [302, {'Location' => url}, []]
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,77 @@
1
+ require_relative 'router/route.rb'
2
+ require_relative 'router/request_builder.rb'
3
+
4
+ module Rack
5
+ class Way
6
+ class Router
7
+ attr_writer :not_found
8
+
9
+ def initialize
10
+ @routes =
11
+ {
12
+ 'GET' => [],
13
+ 'POST' => [],
14
+ 'DELETE' => [],
15
+ 'PUT' => [],
16
+ 'PATCH' => []
17
+ }
18
+
19
+ @namespaces = []
20
+
21
+ @not_found = proc { [404, {}, ['Not found']] }
22
+ end
23
+
24
+ def call(env)
25
+ route = match_route(env)
26
+ request_builder = RequestBuilder.new(env)
27
+
28
+ return render_not_found(request_builder.call) if route.nil?
29
+
30
+ if route.endpoint.respond_to?(:call)
31
+ return route.endpoint.call(request_builder.call(route))
32
+ end
33
+
34
+ route.endpoint.new.call(request_builder.call(route))
35
+ end
36
+
37
+ def add(method, path, endpoint)
38
+ route =
39
+ Route.new("/" + @namespaces.join('/') + put_path_slash(path), endpoint)
40
+
41
+ @routes[method.to_s.upcase].push route
42
+ end
43
+
44
+ def add_not_found(endpoint)
45
+ @not_found = endpoint
46
+ end
47
+
48
+ def append_namespace(name)
49
+ @namespaces.push(name)
50
+ end
51
+
52
+ def clear_last_namespace
53
+ @namespaces =
54
+ @namespaces.first(@namespaces.size - 1)
55
+ end
56
+
57
+ private
58
+
59
+ def put_path_slash(path)
60
+ return '' if (path == '/' || path == '') && @namespaces != []
61
+ return '/' + path if @namespaces != []
62
+ path
63
+ end
64
+
65
+ def render_not_found(env)
66
+ return @not_found.call(env) if @not_found.respond_to?(:call)
67
+
68
+ @not_found.new.call(env)
69
+ end
70
+
71
+ def match_route(env)
72
+ @routes[env["REQUEST_METHOD"]]
73
+ .detect { |route| route.match?(env) }
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,48 @@
1
+ module Rack
2
+ class Way
3
+ class Router
4
+ class RequestBuilder
5
+ def initialize(env)
6
+ @env = env
7
+ end
8
+
9
+ def call(route = nil)
10
+ request = Rack::Request.new(@env)
11
+
12
+ return request if route.nil?
13
+ return request unless route.has_params?
14
+
15
+ update_request_params(request, route)
16
+ end
17
+
18
+ private
19
+
20
+ def update_request_params(request, route)
21
+ splitted_request_path = request.path.split('/')
22
+
23
+ route
24
+ .splitted_path
25
+ .each
26
+ .with_index do |route_word, route_word_position|
27
+ if route_word.start_with?(':')
28
+ param = splitted_request_path[route_word_position]
29
+ param = param.to_i if is_a_integer_string?(param)
30
+
31
+ update_request_param(request, route_word, param)
32
+ end
33
+ end
34
+
35
+ request
36
+ end
37
+
38
+ def is_a_integer_string?(string)
39
+ string =~ /\A[-+]?[0-9]*\.?[0-9]+\Z/
40
+ end
41
+
42
+ def update_request_param(request, word, param)
43
+ request.update_param(word.sub(':', '').to_sym, param)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,55 @@
1
+ module Rack
2
+ class Way
3
+ class Router
4
+ class Route
5
+ attr_reader :endpoint, :splitted_path
6
+
7
+ def initialize(path, endpoint)
8
+ @path = path
9
+ @splitted_path = @path.split('/')
10
+ @endpoint = endpoint
11
+ @params = fetch_params
12
+ end
13
+
14
+ def match?(env)
15
+ if has_params?
16
+ return match_with_params?(env)
17
+ end
18
+
19
+ env['REQUEST_PATH'] == @path
20
+ end
21
+
22
+ def has_params?
23
+ @params != []
24
+ end
25
+
26
+ private
27
+
28
+ def fetch_params
29
+ @splitted_path.select { |value| value.start_with? ':' }
30
+ end
31
+
32
+ def match_with_params?(env)
33
+ splitted_request_path = env['REQUEST_PATH'].split('/')
34
+
35
+ if @splitted_path.size != splitted_request_path.size
36
+ return false
37
+ end
38
+
39
+ matched =
40
+ @splitted_path
41
+ .map
42
+ .with_index do |segment, i|
43
+ if segment.start_with?(':')
44
+ true
45
+ else
46
+ splitted_request_path[i] == segment
47
+ end
48
+ end
49
+
50
+ !matched.include?(false)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-way
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Henrique Fernandez
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-04-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: erubis
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rack
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ description: A very little framework that encourages ruby developers to build 'pure
42
+ Rack' applications when working in projects that need high performance.
43
+ email: hriqueft@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - lib/rack-way.rb
49
+ - lib/rack-way/action.rb
50
+ - lib/rack-way/router.rb
51
+ - lib/rack-way/router/request_builder.rb
52
+ - lib/rack-way/router/route.rb
53
+ homepage: https://github.com/henriquefernandez/rack-way
54
+ licenses:
55
+ - MIT
56
+ metadata: {}
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubygems_version: 3.0.3
73
+ signing_key:
74
+ specification_version: 4
75
+ summary: '"rack-way" come with a router and helper functions to build pure rack projects.'
76
+ test_files: []