hanami-utils 1.3.5 → 2.0.0.alpha2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hanami
2
4
  module Utils
3
5
  # Defines the version
4
6
  #
5
7
  # @since 0.1.0
6
- VERSION = '1.3.5'.freeze
8
+ VERSION = "2.0.0.alpha2"
7
9
  end
8
10
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.5
4
+ version: 2.0.0.alpha2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-25 00:00:00.000000000 Z
11
+ date: 2021-05-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: transproc
14
+ name: dry-transformer
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: '0.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: '0.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: concurrent-ruby
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -78,14 +78,28 @@ dependencies:
78
78
  requirements:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: '3.7'
81
+ version: '3.9'
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: '3.7'
88
+ version: '3.9'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rubocop
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - '='
94
+ - !ruby/object:Gem::Version
95
+ version: '0.91'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - '='
101
+ - !ruby/object:Gem::Version
102
+ version: '0.91'
89
103
  description: Hanami utilities
90
104
  email:
91
105
  - me@lucaguidi.com
@@ -103,19 +117,19 @@ files:
103
117
  - lib/hanami/logger/colorizer.rb
104
118
  - lib/hanami/logger/filter.rb
105
119
  - lib/hanami/logger/formatter.rb
120
+ - lib/hanami/middleware.rb
106
121
  - lib/hanami/utils.rb
107
122
  - lib/hanami/utils/basic_object.rb
108
123
  - lib/hanami/utils/blank.rb
109
124
  - lib/hanami/utils/callbacks.rb
110
125
  - lib/hanami/utils/class.rb
111
126
  - lib/hanami/utils/class_attribute.rb
127
+ - lib/hanami/utils/class_attribute/attributes.rb
112
128
  - lib/hanami/utils/deprecation.rb
113
- - lib/hanami/utils/duplicable.rb
114
129
  - lib/hanami/utils/escape.rb
115
130
  - lib/hanami/utils/file_list.rb
116
131
  - lib/hanami/utils/files.rb
117
132
  - lib/hanami/utils/hash.rb
118
- - lib/hanami/utils/inflector.rb
119
133
  - lib/hanami/utils/io.rb
120
134
  - lib/hanami/utils/json.rb
121
135
  - lib/hanami/utils/kernel.rb
@@ -129,7 +143,7 @@ homepage: http://hanamirb.org
129
143
  licenses:
130
144
  - MIT
131
145
  metadata: {}
132
- post_install_message:
146
+ post_install_message:
133
147
  rdoc_options: []
134
148
  require_paths:
135
149
  - lib
@@ -137,15 +151,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
137
151
  requirements:
138
152
  - - ">="
139
153
  - !ruby/object:Gem::Version
140
- version: 2.3.0
154
+ version: 2.6.0
141
155
  required_rubygems_version: !ruby/object:Gem::Requirement
142
156
  requirements:
143
- - - ">="
157
+ - - ">"
144
158
  - !ruby/object:Gem::Version
145
- version: '0'
159
+ version: 1.3.1
146
160
  requirements: []
147
- rubygems_version: 3.0.6
148
- signing_key:
161
+ rubygems_version: 3.2.4
162
+ signing_key:
149
163
  specification_version: 4
150
164
  summary: Ruby core extentions and Hanami utilities
151
165
  test_files: []
@@ -1,80 +0,0 @@
1
- module Hanami
2
- module Utils
3
- # Safe dup logic
4
- #
5
- # @since 0.6.0
6
- module Duplicable
7
- # Duplicates the given value.
8
- #
9
- # It accepts a block to customize the logic.
10
- #
11
- # The following types aren't duped:
12
- #
13
- # * <tt>NilClass</tt>
14
- # * <tt>FalseClass</tt>
15
- # * <tt>TrueClass</tt>
16
- # * <tt>Symbol</tt>
17
- # * <tt>Numeric</tt>
18
- #
19
- # All the other types are duped via <tt>#dup</tt>
20
- #
21
- # @param value [Object] the value to duplicate
22
- # @param blk [Proc] the optional block to customize the logic
23
- #
24
- # @return [Object] the duped value
25
- #
26
- # @since 0.6.0
27
- #
28
- # @example Basic Usage With Types That Can't Be Duped
29
- # require 'hanami/utils/duplicable'
30
- #
31
- # object = 23
32
- # puts object.object_id # => 47
33
- #
34
- # result = Hanami::Utils::Duplicable.dup(object)
35
- #
36
- # puts result # => 23
37
- # puts result.object_id # => 47 - Same object, because numbers can't be duped
38
- #
39
- # @example Basic Usage With Types That Can Be Duped
40
- # require 'hanami/utils/duplicable'
41
- #
42
- # object = "hello"
43
- # puts object.object_id # => 70172661782360
44
- #
45
- # result = Hanami::Utils::Duplicable.dup(object)
46
- #
47
- # puts result # => "hello"
48
- # puts result.object_id # => 70172671467020 - Different object
49
- #
50
- # @example Custom Logic
51
- # require 'hanami/utils/duplicable'
52
- # require 'hanami/utils/hash'
53
- #
54
- # hash = { a: 1 }
55
- # puts hash.object_id # => 70207105061680
56
- #
57
- # result = Hanami::Utils::Duplicable.dup(hash) do |value|
58
- # case value
59
- # when Hanami::Utils::Hash
60
- # value.deep_dup
61
- # when ::Hash
62
- # Hanami::Utils::Hash.new(value).deep_dup.to_h
63
- # end
64
- # end
65
- #
66
- # puts result # => "{:a=>1}"
67
- # puts result.object_id # => 70207105185500 - Different object
68
- def self.dup(value, &blk)
69
- case value
70
- when NilClass, FalseClass, TrueClass, Symbol, Numeric
71
- value
72
- when v = blk&.call(value)
73
- v
74
- else
75
- value.dup
76
- end
77
- end
78
- end
79
- end
80
- end
@@ -1,494 +0,0 @@
1
- require 'hanami/utils/class_attribute'
2
- require 'hanami/utils/blank'
3
-
4
- module Hanami
5
- module Utils
6
- # String inflector
7
- #
8
- # @since 0.4.1
9
- module Inflector # rubocop:disable Metrics/ModuleLength
10
- # Rules for irregular plurals
11
- #
12
- # @since 0.6.0
13
- # @api private
14
- class IrregularRules
15
- # @since 0.6.0
16
- # @api private
17
- def initialize(rules)
18
- @rules = rules
19
- end
20
-
21
- # @since 0.6.0
22
- # @api private
23
- def add(key, value)
24
- @rules[key.downcase] = value.downcase
25
- end
26
-
27
- # @since 0.6.0
28
- # @api private
29
- def ===(other)
30
- key = extract_last_alphanumeric_token(other)
31
- @rules.key?(key) || @rules.value?(key)
32
- end
33
-
34
- # @since 0.6.0
35
- # @api private
36
- def apply(string)
37
- key = extract_last_alphanumeric_token(string)
38
- result = @rules[key] || @rules.rassoc(key).last
39
-
40
- prefix = if key == string.downcase
41
- string[0]
42
- else
43
- string[0..string.index(key)]
44
- end
45
-
46
- prefix + result[1..-1]
47
- end
48
-
49
- private
50
-
51
- # @since 1.3.3
52
- # @api private
53
- def extract_last_alphanumeric_token(string)
54
- if string.downcase =~ /_([[:alpha:]]*)\z/
55
- Regexp.last_match(1)
56
- else
57
- string.downcase
58
- end
59
- end
60
- end
61
-
62
- # @since 0.4.1
63
- # @api private
64
- A = 'a'.freeze
65
-
66
- # @since 0.4.1
67
- # @api private
68
- CH = 'ch'.freeze
69
-
70
- # @since 0.4.1
71
- # @api private
72
- CHES = 'ches'.freeze
73
-
74
- # @since 0.4.1
75
- # @api private
76
- EAUX = 'eaux'.freeze
77
-
78
- # @since 0.6.0
79
- # @api private
80
- ES = 'es'.freeze
81
-
82
- # @since 0.4.1
83
- # @api private
84
- F = 'f'.freeze
85
-
86
- # @since 0.4.1
87
- # @api private
88
- I = 'i'.freeze
89
-
90
- # @since 0.4.1
91
- # @api private
92
- ICE = 'ice'.freeze
93
-
94
- # @since 0.4.1
95
- # @api private
96
- ICES = 'ices'.freeze
97
-
98
- # @since 0.4.1
99
- # @api private
100
- IDES = 'ides'.freeze
101
-
102
- # @since 0.4.1
103
- # @api private
104
- IES = 'ies'.freeze
105
-
106
- # @since 0.4.1
107
- # @api private
108
- IFE = 'ife'.freeze
109
-
110
- # @since 0.4.1
111
- # @api private
112
- IS = 'is'.freeze
113
-
114
- # @since 0.4.1
115
- # @api private
116
- IVES = 'ives'.freeze
117
-
118
- # @since 0.4.1
119
- # @api private
120
- MA = 'ma'.freeze
121
-
122
- # @since 0.4.1
123
- # @api private
124
- MATA = 'mata'.freeze
125
-
126
- # @since 0.4.1
127
- # @api private
128
- MEN = 'men'.freeze
129
-
130
- # @since 0.4.1
131
- # @api private
132
- MINA = 'mina'.freeze
133
-
134
- # @since 0.6.0
135
- # @api private
136
- NA = 'na'.freeze
137
-
138
- # @since 0.6.0
139
- # @api private
140
- NON = 'non'.freeze
141
-
142
- # @since 0.4.1
143
- # @api private
144
- O = 'o'.freeze
145
-
146
- # @since 0.4.1
147
- # @api private
148
- OES = 'oes'.freeze
149
-
150
- # @since 0.4.1
151
- # @api private
152
- OUSE = 'ouse'.freeze
153
-
154
- # @since 0.4.1
155
- # @api private
156
- RSE = 'rse'.freeze
157
-
158
- # @since 0.4.1
159
- # @api private
160
- RSES = 'rses'.freeze
161
-
162
- # @since 0.4.1
163
- # @api private
164
- S = 's'.freeze
165
-
166
- # @since 0.4.1
167
- # @api private
168
- SES = 'ses'.freeze
169
-
170
- # @since 0.4.1
171
- # @api private
172
- SSES = 'sses'.freeze
173
-
174
- # @since 0.6.0
175
- # @api private
176
- TA = 'ta'.freeze
177
-
178
- # @since 0.4.1
179
- # @api private
180
- UM = 'um'.freeze
181
-
182
- # @since 0.4.1
183
- # @api private
184
- US = 'us'.freeze
185
-
186
- # @since 0.4.1
187
- # @api private
188
- USES = 'uses'.freeze
189
-
190
- # @since 0.4.1
191
- # @api private
192
- VES = 'ves'.freeze
193
-
194
- # @since 0.4.1
195
- # @api private
196
- X = 'x'.freeze
197
-
198
- # @since 0.4.1
199
- # @api private
200
- XES = 'xes'.freeze
201
-
202
- # @since 0.4.1
203
- # @api private
204
- Y = 'y'.freeze
205
-
206
- include Utils::ClassAttribute
207
-
208
- # Irregular rules for plurals
209
- #
210
- # @since 0.6.0
211
- # @api private
212
- class_attribute :plurals
213
- self.plurals = IrregularRules.new(
214
- # irregular
215
- 'cactus' => 'cacti',
216
- 'child' => 'children',
217
- 'corpus' => 'corpora',
218
- 'foot' => 'feet',
219
- 'genus' => 'genera',
220
- 'goose' => 'geese',
221
- 'louse' => 'lice',
222
- 'man' => 'men',
223
- 'mouse' => 'mice',
224
- 'ox' => 'oxen',
225
- 'person' => 'people',
226
- 'quiz' => 'quizzes',
227
- 'sex' => 'sexes',
228
- 'testis' => 'testes',
229
- 'tooth' => 'teeth',
230
- 'woman' => 'women',
231
- # uncountable
232
- 'deer' => 'deer',
233
- 'equipment' => 'equipment',
234
- 'fish' => 'fish',
235
- 'information' => 'information',
236
- 'means' => 'means',
237
- 'money' => 'money',
238
- 'news' => 'news',
239
- 'offspring' => 'offspring',
240
- 'rice' => 'rice',
241
- 'series' => 'series',
242
- 'sheep' => 'sheep',
243
- 'species' => 'species',
244
- 'police' => 'police',
245
- # regressions
246
- # https://github.com/hanami/utils/issues/106
247
- 'album' => 'albums',
248
- 'area' => 'areas'
249
- )
250
-
251
- # Irregular rules for singulars
252
- #
253
- # @since 0.6.0
254
- # @api private
255
- class_attribute :singulars
256
- self.singulars = IrregularRules.new(
257
- # irregular
258
- 'cacti' => 'cactus',
259
- 'children' => 'child',
260
- 'corpora' => 'corpus',
261
- 'feet' => 'foot',
262
- 'genera' => 'genus',
263
- 'geese' => 'goose',
264
- 'lice' => 'louse',
265
- 'men' => 'man',
266
- 'mice' => 'mouse',
267
- 'oxen' => 'ox',
268
- 'people' => 'person',
269
- 'quizzes' => 'quiz',
270
- 'sexes' => 'sex',
271
- 'testes' => 'testis',
272
- 'teeth' => 'tooth',
273
- 'women' => 'woman',
274
- # uncountable
275
- 'deer' => 'deer',
276
- 'equipment' => 'equipment',
277
- 'fish' => 'fish',
278
- 'information' => 'information',
279
- 'means' => 'means',
280
- 'money' => 'money',
281
- 'news' => 'news',
282
- 'offspring' => 'offspring',
283
- 'rice' => 'rice',
284
- 'series' => 'series',
285
- 'sheep' => 'sheep',
286
- 'species' => 'species',
287
- 'police' => 'police',
288
- # fallback
289
- 'areas' => 'area',
290
- 'hives' => 'hive',
291
- 'phases' => 'phase',
292
- 'exercises' => 'exercise',
293
- 'releases' => 'release'
294
- )
295
-
296
- # Block for custom inflection rules.
297
- #
298
- # @param [Proc] blk custom inflections
299
- #
300
- # @since 0.6.0
301
- #
302
- # @see Hanami::Utils::Inflector.exception
303
- # @see Hanami::Utils::Inflector.uncountable
304
- #
305
- # @example
306
- # require 'hanami/utils/inflector'
307
- #
308
- # Hanami::Utils::Inflector.inflections do
309
- # exception 'analysis', 'analyses'
310
- # exception 'alga', 'algae'
311
- # uncountable 'music', 'butter'
312
- # end
313
- def self.inflections(&blk)
314
- class_eval(&blk)
315
- end
316
-
317
- # Add a custom inflection exception
318
- #
319
- # @param [String] singular form
320
- # @param [String] plural form
321
- #
322
- # @since 0.6.0
323
- #
324
- # @see Hanami::Utils::Inflector.inflections
325
- # @see Hanami::Utils::Inflector.uncountable
326
- #
327
- # @example
328
- # require 'hanami/utils/inflector'
329
- #
330
- # Hanami::Utils::Inflector.inflections do
331
- # exception 'alga', 'algae'
332
- # end
333
- def self.exception(singular, plural)
334
- add_to_inflecto(singular, plural)
335
- singulars.add(plural, singular)
336
- plurals.add(singular, plural)
337
- end
338
-
339
- # Since ROM uses Inflecto for it inferences, we need to add an exception to it
340
- # when one is registered against our Inflector.
341
- # @api private
342
- def self.add_to_inflecto(singular, plural)
343
- return unless defined? Inflecto
344
-
345
- Inflecto.inflections.irregular(singular, plural)
346
- end
347
-
348
- # Add an uncountable word
349
- #
350
- # @param [Array<String>] words
351
- #
352
- # @since 0.6.0
353
- #
354
- # @see Hanami::Utils::Inflector.inflections
355
- # @see Hanami::Utils::Inflector.exception
356
- #
357
- # @example
358
- # require 'hanami/utils/inflector'
359
- #
360
- # Hanami::Utils::Inflector.inflections do
361
- # uncountable 'music', 'art'
362
- # end
363
- def self.uncountable(*words)
364
- Array(words).each do |word|
365
- exception(word, word)
366
- end
367
- end
368
-
369
- # Pluralize the given string
370
- #
371
- # @param string [String] a string to pluralize
372
- #
373
- # @return [String,NilClass] the pluralized string, if present
374
- #
375
- # @api private
376
- # @since 0.4.1
377
- #
378
- # rubocop:disable Metrics/AbcSize
379
- # rubocop:disable Metrics/CyclomaticComplexity
380
- # rubocop:disable Metrics/MethodLength
381
- # rubocop:disable Style/PerlBackrefs
382
- def self.pluralize(string)
383
- return string if string.nil? || string =~ Utils::Blank::STRING_MATCHER
384
-
385
- case string
386
- when plurals
387
- plurals.apply(string)
388
- when /\A((.*)[^aeiou])ch\z/
389
- $1 + CHES
390
- when /\A((.*)[^aeiou])y\z/
391
- $1 + IES
392
- when /\A(.*)(ex|ix)\z/
393
- $1 + ICES
394
- when /\A(.*)(eau|#{EAUX})\z/
395
- $1 + EAUX
396
- when /\A(.*)x\z/
397
- $1 + XES
398
- when /\A(.*)ma\z/
399
- string + TA
400
- when /\A(.*)(um|#{A})\z/
401
- $1 + A
402
- when /\A(buffal|domin|ech|embarg|her|mosquit|potat|tomat)#{O}\z/i
403
- $1 + OES
404
- when /\A(.*)(fee)\z/
405
- $1 + $2 + S
406
- when /\A(.*)(?:([^f]))f[e]*\z/
407
- $1 + $2 + VES
408
- when /\A(.*)us\z/
409
- $1 + USES
410
- when /\A(.*)non\z/
411
- $1 + NA
412
- when /\A((.*)[^aeiou])is\z/
413
- $1 + ES
414
- when /\A(.*)ss\z/
415
- $1 + SSES
416
- when /s\z/
417
- string
418
- else
419
- string + S
420
- end
421
- end
422
- # rubocop:enable Style/PerlBackrefs
423
- # rubocop:enable Metrics/AbcSize
424
- # rubocop:enable Metrics/CyclomaticComplexity
425
- # rubocop:enable Metrics/MethodLength
426
-
427
- # Singularize the given string
428
- #
429
- # @param string [String] a string to singularize
430
- #
431
- # @return [String,NilClass] the singularized string, if present
432
- #
433
- # @api private
434
- # @since 0.4.1
435
- #
436
- # rubocop:disable Metrics/AbcSize
437
- # rubocop:disable Metrics/CyclomaticComplexity
438
- # rubocop:disable Metrics/MethodLength
439
- # rubocop:disable Metrics/PerceivedComplexity
440
- # rubocop:disable Style/PerlBackrefs
441
- def self.singularize(string)
442
- return string if string.nil? || string =~ Utils::Blank::STRING_MATCHER
443
-
444
- case string
445
- when singulars
446
- singulars.apply(string)
447
- when /\A.*[^aeiou]#{CHES}\z/
448
- string.sub(CHES, CH)
449
- when /\A.*[^aeiou]#{IES}\z/
450
- string.sub(IES, Y)
451
- when /\A.*#{EAUX}\z/
452
- string.chop
453
- when /\A(.*)#{IDES}\z/
454
- $1 + IS
455
- when /\A(.*)#{US}\z/
456
- $1 + I
457
- when /\A(.*)#{RSES}\z/
458
- $1 + RSE
459
- when /\A(.*)#{SES}\z/
460
- $1 + S
461
- when /\A(.*)#{MATA}\z/
462
- $1 + MA
463
- when /\A(.*)#{OES}\z/
464
- $1 + O
465
- when /\A(.*)#{MINA}\z/
466
- $1 + MEN
467
- when /\A(.*)#{XES}\z/
468
- $1 + X
469
- when /\A(.*)#{IVES}\z/
470
- $1 + IFE
471
- when /\A(.*)#{VES}\z/
472
- $1 + F
473
- when /\A(.*)#{I}\z/
474
- $1 + US
475
- when /\A(.*)ae\z/
476
- $1 + A
477
- when /\A(.*)na\z/
478
- $1 + NON
479
- when /\A(.*)#{A}\z/
480
- $1 + UM
481
- when /[^s]\z/
482
- string
483
- else
484
- string.chop
485
- end
486
- end
487
- # rubocop:enable Style/PerlBackrefs
488
- # rubocop:enable Metrics/AbcSize
489
- # rubocop:enable Metrics/CyclomaticComplexity
490
- # rubocop:enable Metrics/MethodLength
491
- # rubocop:enable Metrics/PerceivedComplexity
492
- end
493
- end
494
- end