Skip to content

Instantly share code, notes, and snippets.

@estum
Created October 23, 2020 10:41
Show Gist options
  • Save estum/655806f9862aaedca9996a08903f13a0 to your computer and use it in GitHub Desktop.
Save estum/655806f9862aaedca9996a08903f13a0 to your computer and use it in GitHub Desktop.
JSONWildcard: A tiny singleton to generate JSON templates.
# frozen_string_literal: true
# A tiny singleton to generate JSON templates.
#
# === Example:
#
# template = JSONWildcard["example" => Array.new(5, "%s")]
# # => {"example":[%1$s,%2$s,%3$s,%4$s,%5$s]}
#
# JSONWildcard.format(template, 1, 2, 3, 4, 5)
# # => {"example":[1,2,3,4,5]}
class JSONWildcard
PATTERN = %r(\"%(?:(\d+)\$)?([sdf])\").freeze
private_constant :PATTERN
# :call-seq:
# JSONWildcard.(serializable_hash) → String
# JSONWildcard[serializable_hash] → String
def self.call(hsh)
matches, last_n = 0, nil
hsh.to_json.gsub(PATTERN) do |s|
match = Regexp.last_match
matches += 1
if match[1].present?
last_n = match[1].to_i
elsif last_n.nil?
last_n = matches
else
last_n += 1
end
"%#{last_n}$#{match[2]}"
end
end
singleton_class.alias_method :[], :call
# :call-seq:
# JSONWildcard.format(template, *values[, serialize: true]) → String
def self.format(json, *sources, serialize: true)
sources.map!(&:to_json) if serialize
sprintf(json, *sources)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment