chespirito 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/chespirito.gemspec +1 -1
- data/lib/chespirito/app.rb +8 -6
- data/lib/chespirito/controller.rb +1 -1
- data/lib/chespirito/request.rb +6 -0
- data/lib/chespirito/routes/route.rb +23 -0
- data/lib/chespirito/routes/route_constraint_checker.rb +33 -0
- data/lib/chespirito/routes/route_utils.rb +14 -0
- data/lib/chespirito/routes/router.rb +65 -0
- metadata +6 -3
- data/lib/chespirito/router.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c4d6e5d80eb4af70ff671777425f063aa79ea43125e68c453ddb1be96f14abd
|
4
|
+
data.tar.gz: 0bb3fcbd997da246fa75b009517a8b53c8e57dffd2cd539db9c925179c5ba33f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed1632d57adc92b16534f172e79de97003a3a97bb1698d330d0517de467722cb495993b563a9ae203f51000d2a58ccd8f64514a86b02d5a2d882effce6ea2852
|
7
|
+
data.tar.gz: 1f850630a40f3da4f642d30f3ce4ee0b81143889ecd47ee3cad57aa11b587cce30c6e8c119305f3e638403cbdfae6238739dd135b80295c2636381397a918beb
|
data/chespirito.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = 'chespirito'
|
5
|
-
spec.version = '0.0.
|
5
|
+
spec.version = '0.0.3'
|
6
6
|
spec.summary = 'Chespirito Ruby web framework'
|
7
7
|
spec.description = 'A dead simple, yet Rack-compatible, web framework written in Ruby'
|
8
8
|
spec.authors = ['Leandro Proença']
|
data/lib/chespirito/app.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative './request'
|
4
|
-
require_relative './router'
|
4
|
+
require_relative './routes/router'
|
5
5
|
|
6
6
|
module Chespirito
|
7
7
|
class App
|
@@ -15,17 +15,19 @@ module Chespirito
|
|
15
15
|
new.tap { |app| yield(app) }
|
16
16
|
end
|
17
17
|
|
18
|
-
def register_route(
|
19
|
-
attrs => [verb, path, trait]
|
20
|
-
|
18
|
+
def register_route(verb, path, trait)
|
21
19
|
@router.register_route(verb, path, trait)
|
22
20
|
end
|
23
21
|
|
24
|
-
def
|
22
|
+
def register_system_route(key, trait)
|
23
|
+
@router.register_system_route(key, trait)
|
24
|
+
end
|
25
|
+
|
26
|
+
def dispatch(request) = @router.dispatch(request)
|
25
27
|
|
26
28
|
def call(env)
|
27
29
|
request = ::Chespirito::Request.build(env)
|
28
|
-
response =
|
30
|
+
response = dispatch(request)
|
29
31
|
|
30
32
|
[
|
31
33
|
response.status,
|
@@ -11,7 +11,7 @@ module Chespirito
|
|
11
11
|
@response = ::Chespirito::Response.new
|
12
12
|
end
|
13
13
|
|
14
|
-
def self.
|
14
|
+
def self.process(action, request)
|
15
15
|
new(request)
|
16
16
|
.tap { |controller| controller.send(action.to_sym) }
|
17
17
|
.then { |controller| controller.response }
|
data/lib/chespirito/request.rb
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Chespirito
|
4
|
+
class Route
|
5
|
+
attr_reader :verb, :path, :controller_klass, :action
|
6
|
+
|
7
|
+
def initialize(*attrs)
|
8
|
+
@verb, @path, @trait = attrs
|
9
|
+
@controller_klass, @action = @trait
|
10
|
+
end
|
11
|
+
|
12
|
+
def key = "#{@verb} #{@path}"
|
13
|
+
end
|
14
|
+
|
15
|
+
class SystemRoute
|
16
|
+
attr_reader :key, :controller_klass, :action
|
17
|
+
|
18
|
+
def initialize(*attrs)
|
19
|
+
@key, @trait = attrs
|
20
|
+
@controller_klass, @action = @trait
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './route_utils'
|
4
|
+
|
5
|
+
module Chespirito
|
6
|
+
class RouteConstraintChecker
|
7
|
+
def initialize(request)
|
8
|
+
@request = request
|
9
|
+
end
|
10
|
+
|
11
|
+
def match_route?(route)
|
12
|
+
return false unless route.respond_to?(:path)
|
13
|
+
return false if route_constraints(route).empty?
|
14
|
+
|
15
|
+
route_constraints(route).size == request_constraints(route).size
|
16
|
+
end
|
17
|
+
|
18
|
+
def extract_params(route)
|
19
|
+
return {} unless route.respond_to?(:path)
|
20
|
+
return {} unless match_route?(route)
|
21
|
+
|
22
|
+
route_constraints(route)
|
23
|
+
.zip(request_constraints(route))
|
24
|
+
.to_h
|
25
|
+
end
|
26
|
+
|
27
|
+
def route_constraints(route) = RouteUtils.constraints(route.path)
|
28
|
+
def request_constraints(route) = request_parts - route_parts(route)
|
29
|
+
|
30
|
+
def route_parts(route) = RouteUtils.parts(route.path)
|
31
|
+
def request_parts = RouteUtils.words(@request.path)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Chespirito
|
4
|
+
class RouteUtils
|
5
|
+
class << self
|
6
|
+
def words(path) = path.split("/").delete_if(&:empty?)
|
7
|
+
def constraints(path) = words(path).select(&method(:constraint?)).map(&method(:remove_colon))
|
8
|
+
def parts(path) = words(path).select(&method(:part?))
|
9
|
+
def part?(word) = !constraint?(word)
|
10
|
+
def constraint?(word) = word.start_with?(":")
|
11
|
+
def remove_colon(word) = word.gsub(":", '')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './route'
|
4
|
+
require_relative './route_constraint_checker'
|
5
|
+
require_relative '../response'
|
6
|
+
|
7
|
+
module Chespirito
|
8
|
+
class Router
|
9
|
+
def initialize
|
10
|
+
@routes = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def register_route(*attrs)
|
14
|
+
route = Route.new(*attrs)
|
15
|
+
|
16
|
+
@routes[route.key] = route
|
17
|
+
end
|
18
|
+
|
19
|
+
def register_system_route(*attrs)
|
20
|
+
route = SystemRoute.new(*attrs)
|
21
|
+
|
22
|
+
@routes[route.key] = route
|
23
|
+
end
|
24
|
+
|
25
|
+
def dispatch(request)
|
26
|
+
route = route_for(request)
|
27
|
+
return not_found_response unless route
|
28
|
+
|
29
|
+
route
|
30
|
+
.controller_klass
|
31
|
+
.process(route.action, request)
|
32
|
+
end
|
33
|
+
|
34
|
+
def route_for(request)
|
35
|
+
simple_route(request) || constraint_route(request) || not_found_route
|
36
|
+
end
|
37
|
+
|
38
|
+
def simple_route(request)
|
39
|
+
@routes["#{request.verb} #{request.path}"]
|
40
|
+
end
|
41
|
+
|
42
|
+
def constraint_route(request)
|
43
|
+
constraint_checker = RouteConstraintChecker.new(request)
|
44
|
+
|
45
|
+
route = @routes.values.find(&constraint_checker.method(:match_route?))
|
46
|
+
return unless route
|
47
|
+
|
48
|
+
route.tap do
|
49
|
+
constraint_checker
|
50
|
+
.extract_params(route)
|
51
|
+
.each { |(name, value)| request.add_param!(name, value) }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def not_found_route = @routes['404'] || @routes[:not_found]
|
56
|
+
|
57
|
+
def not_found_response
|
58
|
+
::Chespirito::Response.new.tap do |response|
|
59
|
+
response.status = 404
|
60
|
+
response.headers = {}
|
61
|
+
response.body = ''
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chespirito
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Leandro Proença
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-05-
|
11
|
+
date: 2022-05-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -53,7 +53,10 @@ files:
|
|
53
53
|
- lib/chespirito/controller.rb
|
54
54
|
- lib/chespirito/request.rb
|
55
55
|
- lib/chespirito/response.rb
|
56
|
-
- lib/chespirito/
|
56
|
+
- lib/chespirito/routes/route.rb
|
57
|
+
- lib/chespirito/routes/route_constraint_checker.rb
|
58
|
+
- lib/chespirito/routes/route_utils.rb
|
59
|
+
- lib/chespirito/routes/router.rb
|
57
60
|
homepage: https://github.com/leandronsp/chespirito
|
58
61
|
licenses:
|
59
62
|
- MIT
|
data/lib/chespirito/router.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative './request'
|
4
|
-
require_relative './response'
|
5
|
-
|
6
|
-
module Chespirito
|
7
|
-
class Router
|
8
|
-
def initialize
|
9
|
-
@routes = {}
|
10
|
-
end
|
11
|
-
|
12
|
-
def register_route(verb, path, trait)
|
13
|
-
@routes[route_key(verb, path)] = trait
|
14
|
-
end
|
15
|
-
|
16
|
-
def lookup(request)
|
17
|
-
controller_klass, action = @routes[route_key(request.verb, request.path)]
|
18
|
-
|
19
|
-
return not_found_response unless controller_klass
|
20
|
-
|
21
|
-
controller_klass.dispatch(action, request)
|
22
|
-
end
|
23
|
-
|
24
|
-
def route_key(verb, path) = "#{verb} #{path}"
|
25
|
-
|
26
|
-
def not_found_response
|
27
|
-
::Chespirito::Response.new.tap do |response|
|
28
|
-
response.status = 404
|
29
|
-
response.headers = {}
|
30
|
-
response.body = ''
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|