lennarb 0.6.1 → 1.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d9cfd70e5b40a64d96f5cd52b748c32a36b796c43e6d490b4df64bc5fae3c781
4
- data.tar.gz: ffc4abf90906f7378879a0d342e74922c01c6ae9d6d59855128d4fd3ec11d40c
3
+ metadata.gz: 9732dfc70b838e4871ffee4a196c8641639e29787f716310ba0d447e90470dd0
4
+ data.tar.gz: '085874f1f8e722aa6e5a8a422422970a66d8bb9e26c24653614571ee1e053c81'
5
5
  SHA512:
6
- metadata.gz: 6d1e7a05a3e931a3163b4103d9900c36163e72e738e0435bc4396fb5f3aeb3c6d044edbdfd8a7fde7512265df91d86dc01a719b7b58ffdf7dc10698a69c1016c
7
- data.tar.gz: 75c64ac16b3fd3599e78c6a9dd04c951137d11b64b11685af4f9d7d0626331aa554564d8786914d129b93e128ebaa54015f0098b75626e5c74bd347e7ece2861
6
+ metadata.gz: c484091928ee8a7d3a75bb7b3279a6915151e2dd9ea01c1d968bec78f4bcdaef166d452e7ba554b0c552ce89b4541cb46a8babbcfe5a1b3c21f88410f5ecf8bd
7
+ data.tar.gz: bb3103c9a7ab43ab5e643c2ec2285acf5127d5fc7d0ec4e8060424468cea94f7d0995eabbed43bbf06deac0aa70f4613a4cbf140e0b002f56381363544a3420e
@@ -43,7 +43,7 @@ class Lennarb
43
43
  subclass.instance_variable_set(:@_before_hooks, Lennarb::RouteNode.new)
44
44
  end
45
45
 
46
- def get(path, &) = @_route.get(path, &)
46
+ def get(...) = @_route.get(...)
47
47
  def put(...) = @_route.put(...)
48
48
  def post(...) = @_route.post(...)
49
49
  def head(...) = @_route.head(...)
@@ -172,13 +172,21 @@ class Lennarb
172
172
  #
173
173
  def redirect(path, status = 302) = throw :halt, [status, { 'location' => path }, []]
174
174
 
175
- # To use a plugin
175
+ # Include a plugin in the application
176
176
  #
177
- # @parameter [String | Symbol] plugin_name
177
+ # @parameter [String] plugin_name
178
+ # @parameter [Array] args
179
+ # @parameter [Block] block
178
180
  #
179
181
  # @returns [void]
180
182
  #
181
- def plugin(plugin_name) = @_route.plugin(plugin_name)
183
+ def plugin(plugin_name, *, &)
184
+ @_route.plugin(plugin_name, *, &)
185
+ plugin_module = @_route.class::Plugin.load(plugin_name)
186
+
187
+ include plugin_module::InstanceMethods if plugin_module.const_defined?(:InstanceMethods)
188
+ extend plugin_module::ClassMethods if plugin_module.const_defined?(:ClassMethods)
189
+ end
182
190
 
183
191
  private
184
192
 
@@ -7,14 +7,29 @@ class Lennarb
7
7
  module Plugin
8
8
  @plugins = {}
9
9
 
10
+ # Register a plugin
11
+ #
12
+ # @parameter [String] name
13
+ # @parameter [Module] mod
14
+ #
15
+ # @returns [void]
16
+ #
10
17
  def self.register(name, mod)
11
18
  @plugins[name] = mod
12
19
  end
13
20
 
21
+ # Load a plugin
22
+ #
23
+ # @parameter [String] name
24
+ #
25
+ # @returns [Module] plugin
26
+ #
14
27
  def self.load(name)
15
- @plugins[name] || raise("Plugin #{name} did not register itself correctly")
28
+ @plugins[name] || raise(LennarbError, "Plugin #{name} did not register itself correctly")
16
29
  end
17
30
 
31
+ # @returns [Hash] plugins
32
+ #
18
33
  def self.plugins = @plugins
19
34
  end
20
35
  end
@@ -5,23 +5,24 @@
5
5
 
6
6
  class Lennarb
7
7
  class RouteNode
8
- attr_accessor :children, :blocks, :param_key
8
+ attr_accessor :static_children, :dynamic_children, :blocks, :param_key
9
9
 
10
- # Initialize the route node
10
+ # Initializes the RouteNode class.
11
11
  #
12
12
  # @return [RouteNode]
13
13
  #
14
14
  def initialize
15
- @children = {}
16
- @blocks = {}
17
- @param_key = nil
15
+ @blocks = {}
16
+ @param_key = nil
17
+ @static_children = {}
18
+ @dynamic_children = {}
18
19
  end
19
20
 
20
21
  # Add a route to the route node
21
22
  #
22
- # @parameter [Array] parts
23
- # @parameter [String] http_method
24
- # @parameter [Proc] block
23
+ # @parameter parts [Array<String>] The parts of the route
24
+ # @parameter http_method [Symbol] The HTTP method of the route
25
+ # @parameter block [Proc] The block to be executed when the route is matched
25
26
  #
26
27
  # @return [void]
27
28
  #
@@ -30,44 +31,42 @@ class Lennarb
30
31
 
31
32
  parts.each do |part|
32
33
  if part.start_with?(':')
33
- key = :param
34
- current_node.children[key] ||= RouteNode.new
35
- current_node = current_node.children[key]
36
- current_node.param_key = part[1..].to_sym
34
+ param_sym = part[1..].to_sym
35
+ current_node.dynamic_children[param_sym] ||= RouteNode.new
36
+ dynamic_node = current_node.dynamic_children[param_sym]
37
+ dynamic_node.param_key = param_sym
38
+ current_node = dynamic_node
37
39
  else
38
- key = part
39
- current_node.children[key] ||= RouteNode.new
40
- current_node = current_node.children[key]
40
+ current_node.static_children[part] ||= RouteNode.new
41
+ current_node = current_node.static_children[part]
41
42
  end
42
43
  end
43
44
 
44
45
  current_node.blocks[http_method] = block
45
46
  end
46
47
 
47
- # Match a route to the route node
48
- #
49
- # @parameter [Array] parts
50
- # @parameter [String] http_method
51
- #
52
- # @return [Array]
53
- #
54
- def match_route(parts, http_method)
55
- current_node = self
56
- params = {}
48
+ def match_route(parts, http_method, params: {})
49
+ if parts.empty?
50
+ return [blocks[http_method], params] if blocks[http_method]
51
+ else
52
+ part = parts.first
53
+ rest = parts[1..]
57
54
 
58
- parts.each do |part|
59
- return [nil, nil] unless current_node.children.key?(part) || current_node.children[:param]
55
+ if static_children.key?(part)
56
+ result_block, result_params = static_children[part].match_route(rest, http_method, params:)
57
+ return [result_block, result_params] if result_block
58
+ end
60
59
 
61
- if current_node.children.key?(part)
62
- current_node = current_node.children[part]
63
- else
64
- param_node = current_node.children[:param]
65
- params[param_node.param_key] = part
66
- current_node = param_node
60
+ dynamic_children.each_value do |dyn_node|
61
+ new_params = params.dup
62
+ new_params[dyn_node.param_key] = part
63
+ result_block, result_params = dyn_node.match_route(rest, http_method, params: new_params)
64
+
65
+ return [result_block, result_params] if result_block
67
66
  end
68
67
  end
69
68
 
70
- [current_node.blocks[http_method], params]
69
+ [nil, nil]
71
70
  end
72
71
  end
73
72
  end
@@ -4,7 +4,7 @@
4
4
  # Copyright, 2023-2024, by Aristóteles Coutinho.
5
5
 
6
6
  class Lennarb
7
- VERSION = '0.6.1'
7
+ VERSION = '1.0.1'
8
8
 
9
9
  public_constant :VERSION
10
10
  end
data/lib/lennarb.rb CHANGED
@@ -27,6 +27,11 @@ class Lennarb
27
27
  #
28
28
  attr_reader :_root
29
29
 
30
+ # @attribute [r] applied_plugins
31
+ # @returns [Array]
32
+ #
33
+ attr_reader :_applied_plugins
34
+
30
35
  # Initialize the application
31
36
  #
32
37
  # @yield { ... } The application
@@ -35,6 +40,7 @@ class Lennarb
35
40
  #
36
41
  def initialize
37
42
  @_root = RouteNode.new
43
+ @_applied_plugins = []
38
44
  yield self if block_given?
39
45
  end
40
46
 
@@ -90,15 +96,23 @@ class Lennarb
90
96
  def delete(path, &block) = add_route(path, :DELETE, block)
91
97
  def options(path, &block) = add_route(path, :OPTIONS, block)
92
98
 
93
- # Register a plugin
99
+ # Add plugin to extend the router
94
100
  #
95
- # @parameter [String | Symbol] plugin_name
101
+ # @parameter [String] plugin_name
102
+ # @parameter [args] *args
103
+ # @parameter [Block] block
96
104
  #
97
105
  # @returns [void]
98
106
  #
99
- def plugin(plugin_name)
100
- plugin_module = Lennarb::Plugin.load(plugin_name)
101
- extend plugin_module
107
+ def plugin(plugin_name, *, &)
108
+ return if @_applied_plugins.include?(plugin_name)
109
+
110
+ plugin_module = Plugin.load(plugin_name)
111
+ extend plugin_module::InstanceMethods if defined?(plugin_module::InstanceMethods)
112
+ self.class.extend plugin_module::ClassMethods if defined?(plugin_module::ClassMethods)
113
+ plugin_module.setup(self.class, *, &) if plugin_module.respond_to?(:setup)
114
+
115
+ @_applied_plugins << plugin_name
102
116
  end
103
117
 
104
118
  private
data/readme.md CHANGED
@@ -40,6 +40,8 @@ Plese see [Performance](https://aristotelesbr.github.io/lennarb/guides/performan
40
40
 
41
41
  - [Performance](https://aristotelesbr.github.io/lennarb/guides/performance/index.html) - The **Lennarb** is very fast. The following benchmarks were performed on a MacBook Pro (Retina, 13-inch, Early 2013) with 2,7 GHz Intel Core i7 and 8 GB 1867 MHz DDR3. Based on [jeremyevans/r10k](https://github.com/jeremyevans/r10k) using the following [template build](static/r10k/build/lennarb.rb).
42
42
 
43
+ - [Plugin](https://aristotelesbr.github.io/lennarb/guides/plugin/index.html) - You can create your plugins to extend the functionality of the framework.
44
+
43
45
  - [Response](https://aristotelesbr.github.io/lennarb/guides/response/index.html) - This is the response guide.
44
46
  The `res` object is used to send a response to the client. The Lennarb use a custom response object to send responses to the client. The `res` object is an instance of `Lennarb::Response`.
45
47
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lennarb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aristóteles Coutinho
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-05-17 00:00:00.000000000 Z
11
+ date: 2024-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -115,33 +115,33 @@ dependencies:
115
115
  - !ruby/object:Gem::Version
116
116
  version: '6.4'
117
117
  - !ruby/object:Gem::Dependency
118
- name: rake
118
+ name: rack-test
119
119
  requirement: !ruby/object:Gem::Requirement
120
120
  requirements:
121
121
  - - "~>"
122
122
  - !ruby/object:Gem::Version
123
- version: '13.1'
123
+ version: '2.1'
124
124
  type: :development
125
125
  prerelease: false
126
126
  version_requirements: !ruby/object:Gem::Requirement
127
127
  requirements:
128
128
  - - "~>"
129
129
  - !ruby/object:Gem::Version
130
- version: '13.1'
130
+ version: '2.1'
131
131
  - !ruby/object:Gem::Dependency
132
- name: rack-test
132
+ name: rake
133
133
  requirement: !ruby/object:Gem::Requirement
134
134
  requirements:
135
135
  - - "~>"
136
136
  - !ruby/object:Gem::Version
137
- version: '2.1'
137
+ version: '13.1'
138
138
  type: :development
139
139
  prerelease: false
140
140
  version_requirements: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - "~>"
143
143
  - !ruby/object:Gem::Version
144
- version: '2.1'
144
+ version: '13.1'
145
145
  - !ruby/object:Gem::Dependency
146
146
  name: rubocop
147
147
  requirement: !ruby/object:Gem::Requirement
@@ -192,7 +192,7 @@ homepage: https://aristotelesbr.github.io/lennarb
192
192
  licenses:
193
193
  - MIT
194
194
  metadata:
195
- allowed_push_host: https://rubygems.org/gems/lennarb
195
+ allowed_push_host: https://rubygems.org
196
196
  changelog_uri: https://github.com/aristotelesbr/lennarb/blob/master/changelog.md
197
197
  homepage_uri: https://aristotelesbr.github.io/lennarb
198
198
  rubygems_mfa_required: 'true'
@@ -212,7 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
212
212
  - !ruby/object:Gem::Version
213
213
  version: '0'
214
214
  requirements: []
215
- rubygems_version: 3.5.9
215
+ rubygems_version: 3.5.11
216
216
  signing_key:
217
217
  specification_version: 4
218
218
  summary: A lightweight and experimental web framework for Ruby.