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