dry-inflector 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c399013c00255e60a1adc6c44984238b5b331a9d8432489a189131ac0e7545b3
4
- data.tar.gz: a59e33a3ca433c23bd0248413374b21da91a43d2ac666b1e30033f1e04d144de
3
+ metadata.gz: 7cccc4cd092473c4c5dfefd8830e97c987fbb6cd6039b6253fd973a0b4d5b8ac
4
+ data.tar.gz: 6aca715e9ab5497c0f325691783e92a10035b27a3e6fdf483df38b7fb306d6ad
5
5
  SHA512:
6
- metadata.gz: 9e6ef7a7de2938808c7f01344335d370793a6d0cfa64d0afa42a6481f60cf84bc66ae8080f32706908421d3c13bb5650ab8368fe881bd5c268a3eaafcd9f1da6
7
- data.tar.gz: 30cf65fc5594d8352b1d43b113f98b37b0e01b88e20301c4d02e11116030fcc16acb174c730953876c7337ada68c57b882c3f061a36788511a2763041374585e
6
+ metadata.gz: 2c9c21e1611fe3bafd8cf7e303b5030c1ba3f777fd397a58f2dfba77f8be05b49fdece384e49d82d43043e388ca3fc1f1c6c84508fdfdac02ce9851edfee1dba
7
+ data.tar.gz: c83c9d597c611194642fe6aed04b3c5f6e37ec9fa212b3501a13c93010305f9c339875a09ba123b8a97fa89f567e90c110af9ac76317f4c16749a5e91601b57e
@@ -2,10 +2,20 @@
2
2
 
3
3
  Inflector for Ruby
4
4
 
5
+ ## v0.1.2 - to be released
6
+
7
+ ### Added
8
+
9
+ - [Gustavo Caso & Nikita Shilnikov] Added support for acronyms
10
+
11
+ [Compare v0.1.1...master](https://github.com/dry-rb/dry-inflector/compare/v0.1.1...master)
12
+
5
13
  ## v0.1.1 - 2017-11-18
6
14
  ### Fixed
7
15
  - [Luca Guidi & Abinoam P. Marques Jr.] Ensure `Dry::Inflector#ordinalize` to work for all the numbers from 0 to 100
8
16
 
17
+ [Compare v0.1.0...v0.1.1](https://github.com/dry-rb/dry-inflector/compare/v0.1.0...v0.1.1)
18
+
9
19
  ## v0.1.0 - 2017-11-17
10
20
  ### Added
11
21
  - [Luca Guidi] Introduced `Dry::Inflector#pluralize`
@@ -47,7 +47,15 @@ module Dry
47
47
  # inflector = Dry::Inflector.new
48
48
  # inflector.camelize("dry/inflector") # => "Dry::Inflector"
49
49
  def camelize(input)
50
- input.to_s.gsub(/\/(.?)/) { "::#{Regexp.last_match(1).upcase}" }.gsub(/(?:\A|_)(.)/) { Regexp.last_match(1).upcase }
50
+ input = input.to_s.dup
51
+ input.sub!(/^[a-z\d]*/) { |match| inflections.acronyms.apply_to(match) }
52
+ input.gsub!(%r{(?:_|(/))([a-z\d]*)}i) do
53
+ m1 = Regexp.last_match(1)
54
+ m2 = Regexp.last_match(2)
55
+ "#{m1}#{inflections.acronyms.apply_to(m2)}"
56
+ end
57
+ input.gsub!("/", "::")
58
+ input
51
59
  end
52
60
 
53
61
  # Find a constant with the name specified in the argument string
@@ -134,10 +142,13 @@ module Dry
134
142
  def humanize(input)
135
143
  input = input.to_s
136
144
  result = inflections.humans.apply_to(input)
137
- result.gsub!(/_id\z/, "")
145
+ result.chomp!("_id")
138
146
  result.tr!("_", " ")
139
- result.capitalize!
140
- result
147
+ match = /(?<separator>\W)/.match(result)
148
+ separator = match ? match[:separator] : DEFAULT_SEPARATOR
149
+ result.split(separator).map.with_index { |word, index|
150
+ inflections.acronyms.apply_to(word, index.zero?)
151
+ }.join(separator)
141
152
  end
142
153
 
143
154
  # Creates a foreign key name
@@ -151,7 +162,7 @@ module Dry
151
162
  # inflector = Dry::Inflector.new
152
163
  # inflector.foreign_key("Message") => "message_id"
153
164
  def foreign_key(input)
154
- "#{underscorize(demodulize(input))}_id"
165
+ "#{underscore(demodulize(input))}_id"
155
166
  end
156
167
 
157
168
  # Ordinalize a number
@@ -237,7 +248,7 @@ module Dry
237
248
  # inflector.tableize("Book") # => "books"
238
249
  def tableize(input)
239
250
  input = input.to_s.gsub(/::/, "_")
240
- pluralize(underscorize(input))
251
+ pluralize(underscore(input))
241
252
  end
242
253
 
243
254
  # Underscore a string
@@ -253,8 +264,17 @@ module Dry
253
264
  # inflector = Dry::Inflector.new
254
265
  # inflector.underscore("dry-inflector") # => "dry_inflector"
255
266
  def underscore(input)
256
- input = input.to_s.gsub(/::/, "/")
257
- underscorize(input)
267
+ input = input.to_s.gsub("::", "/")
268
+ input.gsub!(inflections.acronyms.regex) do
269
+ m1 = Regexp.last_match(1)
270
+ m2 = Regexp.last_match(2)
271
+ "#{m1 ? '_' : '' }#{m2.downcase}"
272
+ end
273
+ input.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
274
+ input.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
275
+ input.tr!("-", "_")
276
+ input.downcase!
277
+ input
258
278
  end
259
279
 
260
280
  # Check if the input is an uncountable word
@@ -274,18 +294,12 @@ module Dry
274
294
  # @api private
275
295
  ORDINALIZE_TH = (11..13).each_with_object({}) { |n, ret| ret[n] = true }.freeze
276
296
 
277
- # @since 0.1.0
297
+ # @since 0.1.2
278
298
  # @api private
279
- attr_reader :inflections
299
+ DEFAULT_SEPARATOR = " "
280
300
 
281
301
  # @since 0.1.0
282
302
  # @api private
283
- def underscorize(input)
284
- input.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
285
- input.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
286
- input.tr!("-", "_")
287
- input.downcase!
288
- input
289
- end
303
+ attr_reader :inflections
290
304
  end
291
305
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dry
4
+ class Inflector
5
+ # A set of acronyms
6
+ #
7
+ # @since 0.1.2
8
+ # @api private
9
+ class Acronyms
10
+ attr_reader :regex
11
+
12
+ # @since 0.1.2
13
+ # @api private
14
+ def initialize
15
+ @rules = {}
16
+ define_regex_patterns
17
+ end
18
+
19
+ # @since 0.1.2
20
+ # @api private
21
+ def apply_to(word, capitalize = true)
22
+ @rules[word.downcase] || (capitalize ? word.capitalize : word)
23
+ end
24
+
25
+ # @since 0.1.2
26
+ # @api private
27
+ def add(rule, replacement)
28
+ @rules[rule] = replacement
29
+ define_regex_patterns
30
+ end
31
+
32
+ private
33
+
34
+ # @since 0.1.2
35
+ # @api private
36
+ def define_regex_patterns
37
+ regex = @rules.empty? ? /(?=a)b/ : /#{@rules.values.join("|")}/
38
+ @regex = /(?:(?<=([A-Za-z\d]))|\b)(#{regex})(?=\b|[^a-z])/
39
+ end
40
+ end
41
+ end
42
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "set"
4
4
  require "dry/inflector/rules"
5
+ require "dry/inflector/acronyms"
5
6
 
6
7
  module Dry
7
8
  class Inflector
@@ -57,6 +58,14 @@ module Dry
57
58
  # @api private
58
59
  attr_reader :humans
59
60
 
61
+ # Acronyms
62
+ #
63
+ # @return [Dry::Inflector::Acronyms]
64
+ #
65
+ # @since 0.1.2
66
+ # @api private
67
+ attr_reader :acronyms
68
+
60
69
  # Instantiate the rules
61
70
  #
62
71
  # @return [Dry::Inflector::Inflections]
@@ -69,6 +78,7 @@ module Dry
69
78
  @singulars = Rules.new
70
79
  @humans = Rules.new
71
80
  @uncountables = Set[]
81
+ @acronyms = Acronyms.new
72
82
 
73
83
  yield(self) if block_given?
74
84
  end
@@ -160,6 +170,28 @@ module Dry
160
170
  uncountables.merge(words.flatten)
161
171
  end
162
172
 
173
+ # Add one or more acronyms
174
+ #
175
+ # Acronyms affect how basic operations are performed, such
176
+ # as camelize/underscore.
177
+ #
178
+ # @param words [Array<String>] a list of acronyms
179
+ #
180
+ # @since 0.1.2
181
+ #
182
+ # @example
183
+ # require "dry/inflector"
184
+ #
185
+ # inflector = Dry::Inflector.new do |inflections|
186
+ # inflections.acronym "HTML"
187
+ # end
188
+ #
189
+ # inflector.camelize("html") # => "HTML"
190
+ # inflector.underscore("HTMLIsFun") # => "html_is_fun"
191
+ def acronym(*words)
192
+ words.each { |word| @acronyms.add(word.downcase, word) }
193
+ end
194
+
163
195
  # Add a custom humanize rule
164
196
  #
165
197
  # Specifies a humanized form of a string by a regular expression rule or by a string mapping.
@@ -18,6 +18,7 @@ module Dry
18
18
  singular(inflect)
19
19
  irregular(inflect)
20
20
  uncountable(inflect)
21
+ acronyms(inflect)
21
22
  end
22
23
 
23
24
  # @since 0.1.0
@@ -101,7 +102,13 @@ module Dry
101
102
  inflect.uncountable(%w[hovercraft moose deer milk rain Swiss grass equipment information rice money species series fish sheep jeans])
102
103
  end
103
104
 
104
- private_class_method :plural, :singular, :irregular, :uncountable
105
+ # @since 0.1.2
106
+ # @api private
107
+ def self.acronyms(inflect)
108
+ inflect.acronym(*%w[JSON HTTP OpenSSL HMAC])
109
+ end
110
+
111
+ private_class_method :plural, :singular, :irregular, :uncountable, :acronyms
105
112
  end
106
113
  # rubocop:enable Metrics/MethodLength
107
114
  # rubocop:enable Metrics/AbcSize
@@ -3,6 +3,6 @@
3
3
  module Dry
4
4
  class Inflector
5
5
  # @since 0.1.0
6
- VERSION = "0.1.1"
6
+ VERSION = "0.1.2"
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-inflector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2017-11-18 00:00:00.000000000 Z
13
+ date: 2018-04-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -82,6 +82,7 @@ files:
82
82
  - README.md
83
83
  - dry-inflector.gemspec
84
84
  - lib/dry/inflector.rb
85
+ - lib/dry/inflector/acronyms.rb
85
86
  - lib/dry/inflector/inflections.rb
86
87
  - lib/dry/inflector/inflections/defaults.rb
87
88
  - lib/dry/inflector/rules.rb
@@ -107,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
108
  version: '0'
108
109
  requirements: []
109
110
  rubyforge_project:
110
- rubygems_version: 2.7.1
111
+ rubygems_version: 2.7.6
111
112
  signing_key:
112
113
  specification_version: 4
113
114
  summary: DRY Inflector