module Readthis::Expanders

Expander methods are used to transform an object into a string suitable for use as a cache key.

Public Class Methods

expand_key(key) click to toggle source

Expand an object into a suitable cache key.

The behavior of `expand_key` is largely modeled on the `expand_cache_key` method from `ActiveSupport::Cache`, with some subtle additions.

@param [Object] key An object to stringify. Arrays, hashes, and objects

that respond to either `cache_key` or `to_param` have direct support.
All other objects will be coerced to a string, and frozen strings will
be duplicated.

@return [String] A cache key string.

@example String expansion

Readthis::Expanders.expand_key('typical-key')
'typical-key'

@example Array string expansion

Readthis::Expanders.expand_key(['a', 'b', [:c, 'd'], 1])
'a/b/c/d/1'

@example Hash expansion

Readthis::Expanders.expand_key(c: 1, 'a' => 3, b: 2)
'a=3/b=2/c=1'
# File lib/readthis/expanders.rb, line 32
def self.expand_key(key)
  case
  when key.is_a?(String)
    key.frozen? ? key.dup : key
  when key.is_a?(Array)
    key.flat_map { |elem| expand_key(elem) }.join('/')
  when key.is_a?(Hash)
    key
      .sort_by { |hkey, _| hkey.to_s }
      .map { |hkey, val| "#{hkey}=#{val}" }
      .join('/')
  when key.respond_to?(:cache_key)
    key.cache_key
  when key.respond_to?(:to_param)
    key.to_param
  else
    key.to_s
  end
end
namespace_key(key, namespace = nil) click to toggle source

Prepend a namespace to a key after expanding it.

@param [Object] key An object to stringify. @param [String] namespace An optional namespace to prepend, if `nil` it

is ignored.

@return [String] A binary encoded string combining the namespace and key.

@example Applying a namespace

Knuckles::Expanders.namespace_key('alpha', 'greek')
'greek:alpha'

@example Omitting a namespace

Knuckles::Expanders.namespace_key('alpha', nil)
'alpha'
# File lib/readthis/expanders.rb, line 70
def self.namespace_key(key, namespace = nil)
  expanded = expand_key(key)

  if namespace
    "#{namespace}:#{expanded}"
  else
    expanded
  end.force_encoding(Encoding::BINARY)
end