# frozen_string_literal: true module Refinements # Refinements for Strings. module Strings refine String.singleton_class do def delimiters %r([a-z][A-Z]|\s*\-\s*|\s*\/\s*|\s*\:+\s*|\s*\_\s*|\s+) end end # rubocop:disable Metrics/BlockLength refine String do def first number = 0 return self if empty? max = Integer number return self[0] if max.zero? return "" if max.negative? self[0..(max - 1)] end # :reek:TooManyStatements def last number = 0 return self if empty? min = Integer number max = size - 1 return self[max] if min.zero? return "" if min.negative? self[(min + 1)..max] end def blank? match?(/\A\s*\z/) end def up return self if empty? first.upcase + self[1, size] end def down return self if empty? first.downcase + self[1, size] end def camelcase if match?(self.class.delimiters) result = join_parts split(%r(\s*\-\s*|\s*\/\s*|\s*\:+\s*)), method: :up, delimiter: "::" join_parts result.split(/\s*\_\s*|\s+/), method: :up else up end end def snakecase if match?(self.class.delimiters) result = join_parts split(%r(\s*\-\s*|\s*\/\s*|\s*\:+\s*)), method: :down, delimiter: "/" join_parts result.split(/(?=[A-Z])|\s*\_\s*|\s+/), method: :down, delimiter: "_" else downcase end end def titleize if match?(self.class.delimiters) result = join_parts split(/(?=[A-Z])|\s*\_\s*|\s*\-\s*|\s+/), method: :up, delimiter: " " join_parts result.split(%r(\s*\/\s*|\s*\:+\s*)), method: :up, delimiter: "/" else capitalize end end private # :reek:DuplicateMethodCall # :reek:UtilityFunction def join_parts parts, method:, delimiter: "" parts.reduce "" do |result, part| next part.__send__(method) if result.empty? "#{result}#{delimiter}#{part.__send__ method}" end end end # rubocop:enable Metrics/BlockLength end end