module Sprockets::ProcessorUtils
def call_processor(processor, input)
input - Hash of input data to pass to processor
processor - Processor callables
Public: Invoke processor.
def call_processor(processor, input) metadata = (input[:metadata] || {}).dup metadata[:data] = input[:data] case result = processor.call({data: "", metadata: {}}.merge(input)) when NilClass metadata when Hash metadata.merge(result) when String metadata.merge(data: result) else raise TypeError, "invalid processor return type: #{result.class}" end end
def call_processors(processors, input)
input - Hash of input data to pass to each processor
processors - Array of processor callables
bundle.call(uglify.call(coffee.call(input)))
Think about:
The right to left order processing mirrors standard function composition.
Public: Invoke list of processors in right to left order.
def call_processors(processors, input) data = input[:data] || "" metadata = (input[:metadata] || {}).dup processors.reverse_each do |processor| result = call_processor(processor, input.merge(data: data, metadata: metadata)) data = result.delete(:data) metadata.merge!(result) end metadata.merge(data: data) end
def compose_processors(*processors)
processors - Array of processors callables
Public: Compose processors in right to left order.
def compose_processors(*processors) context = self if processors.length == 1 obj = method(:call_processor).to_proc.curry[processors.first] else obj = method(:call_processors).to_proc.curry[processors] end metaclass = (class << obj; self; end) metaclass.send(:define_method, :cache_key) do context.processors_cache_keys(processors) end obj end
def processor_cache_key(processor)
processor - Processor function
Internal: Get processor defined cached key.
def processor_cache_key(processor) processor.cache_key if processor.respond_to?(:cache_key) end
def processors_cache_keys(processors)
processors - Array of processor functions
Internal: Get combined cache keys for set of processors.
def processors_cache_keys(processors) processors.map { |processor| processor_cache_key(processor) } end
def valid_processor_metadata_value?(value)
value - Any Object
Internal: Validate object is in validate metadata whitelist.
def valid_processor_metadata_value?(value) if VALID_METADATA_VALUE_TYPES_HASH[value.class] true elsif VALID_METADATA_COMPOUND_TYPES_HASH[value.class] value.all? { |v| valid_processor_metadata_value?(v) } else false end end
def validate_processor_result!(result)
result - Metadata Hash returned from call_processors
raise a friendly user error message.
Internal: Validate returned result of calling a processor pipeline and
def validate_processor_result!(result) if !result.instance_of?(Hash) raise TypeError, "processor metadata result was expected to be a Hash, but was #{result.class}" end if !result[:data].instance_of?(String) raise TypeError, "processor :data was expected to be a String, but as #{result[:data].class}" end result.each do |key, value| if !key.instance_of?(Symbol) raise TypeError, "processor metadata[#{key.inspect}] expected to be a Symbol" end if !valid_processor_metadata_value?(value) raise TypeError, "processor metadata[:#{key}] returned a complex type: #{value.inspect}\n" + "Only #{VALID_METADATA_TYPES.to_a.join(", ")} maybe used." end end result end