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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -0
- data/README.md +5 -15
- data/hanami-utils.gemspec +19 -16
- data/lib/hanami-utils.rb +3 -1
- data/lib/hanami/interactor.rb +70 -36
- data/lib/hanami/logger.rb +13 -13
- data/lib/hanami/logger/colorizer.rb +10 -10
- data/lib/hanami/logger/filter.rb +74 -9
- data/lib/hanami/logger/formatter.rb +7 -7
- data/lib/hanami/middleware.rb +11 -0
- data/lib/hanami/utils.rb +12 -26
- data/lib/hanami/utils/basic_object.rb +7 -7
- data/lib/hanami/utils/blank.rb +9 -9
- data/lib/hanami/utils/callbacks.rb +24 -3
- data/lib/hanami/utils/class.rb +3 -56
- data/lib/hanami/utils/class_attribute.rb +23 -12
- data/lib/hanami/utils/class_attribute/attributes.rb +45 -0
- data/lib/hanami/utils/deprecation.rb +3 -1
- data/lib/hanami/utils/escape.rb +275 -271
- data/lib/hanami/utils/file_list.rb +24 -2
- data/lib/hanami/utils/files.rb +16 -22
- data/lib/hanami/utils/hash.rb +24 -363
- data/lib/hanami/utils/io.rb +2 -0
- data/lib/hanami/utils/json.rb +5 -3
- data/lib/hanami/utils/kernel.rb +22 -21
- data/lib/hanami/utils/load_paths.rb +6 -4
- data/lib/hanami/utils/path_prefix.rb +38 -6
- data/lib/hanami/utils/query_string.rb +1 -1
- data/lib/hanami/utils/shell_color.rb +9 -9
- data/lib/hanami/utils/string.rb +44 -470
- data/lib/hanami/utils/version.rb +3 -1
- metadata +30 -16
- data/lib/hanami/utils/duplicable.rb +0 -80
- data/lib/hanami/utils/inflector.rb +0 -494
data/lib/hanami/utils/version.rb
CHANGED
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:
|
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:
|
11
|
+
date: 2021-05-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
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
|
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
|
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.
|
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.
|
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.
|
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:
|
159
|
+
version: 1.3.1
|
146
160
|
requirements: []
|
147
|
-
rubygems_version: 3.
|
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
|