rabl-rails/lib/rabl-fast-json/compiler.rb

102 lines
2.4 KiB
Ruby
Raw Normal View History

2012-02-22 18:14:00 +00:00
module RablFastJson
class Compiler
2012-03-02 13:39:20 +00:00
include Helpers
2012-02-22 18:14:00 +00:00
2012-03-02 10:32:11 +00:00
def initialize(context = nil)
2012-02-22 18:14:00 +00:00
@context = context
2012-02-23 11:56:45 +00:00
@glue_count = 0
2012-02-22 18:14:00 +00:00
end
def compile_source(source)
@template = CompiledTemplate.new
instance_eval(source)
@template
end
2012-02-23 11:04:55 +00:00
def compile_block(&block)
@template = {}
instance_eval(&block)
@template
end
2012-02-22 18:14:00 +00:00
def attribute(*args)
if args.first.is_a?(Hash)
args.first.each_pair { |k, v| @template[v] = k }
else
args.each { |name| @template[name] = name }
end
end
alias_method :attributes, :attribute
2012-02-23 11:04:55 +00:00
def child(name_or_data, options = {}, &block)
2012-02-23 11:56:45 +00:00
data, name = extract_data_and_name(name_or_data)
2012-03-02 13:39:20 +00:00
name = options[:root] if root_given?(options)
if partial_given?(options)
template = Library.instance.get(options[:partial], @context)
@template[name] = template.merge!(:_data => data)
else
_compile_sub_template(name, data, &block)
end
2012-02-23 11:56:45 +00:00
end
def glue(data, &block)
return unless block_given?
name = :"_glue#{@glue_count}"
@glue_count += 1
_compile_sub_template(name, data, &block)
2012-02-23 11:04:55 +00:00
end
def node(name, options = {}, &block)
condition = options[:if]
if condition.present?
if condition.is_a?(Proc)
@template[name] = [condition, block]
else
@template[name] = block if condition
end
else
@template[name] = block
end
2012-02-23 11:04:55 +00:00
end
alias_method :code, :node
2012-02-22 18:14:00 +00:00
def collection(data, options = {})
2012-02-27 13:49:34 +00:00
object(data)
2012-03-02 13:59:01 +00:00
@template.root_name = options[:root] if root_given?(options)
2012-02-27 13:49:34 +00:00
end
def extends(path)
2012-03-02 10:32:11 +00:00
t = Library.instance.get(path, @context)
2012-02-27 13:49:34 +00:00
@template.merge!(t.source)
2012-02-22 18:14:00 +00:00
end
def object(data)
2012-02-23 11:56:45 +00:00
data, name = extract_data_and_name(data)
@template.data, @template.root_name = data, name
2012-02-22 18:14:00 +00:00
end
2012-02-27 13:49:34 +00:00
def method_missing(name, *args, &block)
@context.respond_to?(name) ? @context.send(name, *args, &block) : super
end
2012-02-22 18:14:00 +00:00
protected
2012-02-23 11:56:45 +00:00
def extract_data_and_name(name_or_data)
2012-02-23 11:04:55 +00:00
case name_or_data
when Symbol
[name_or_data, name_or_data]
when Hash
name_or_data.first
else
2012-02-23 11:56:45 +00:00
name_or_data
2012-02-23 11:04:55 +00:00
end
end
2012-02-23 11:56:45 +00:00
def _compile_sub_template(name, data, &block)
2012-03-02 10:32:11 +00:00
compiler = Compiler.new(@context)
2012-02-23 11:56:45 +00:00
template = compiler.compile_block(&block)
@template[name] = template.merge!(:_data => data)
end
2012-02-22 18:14:00 +00:00
end
end