66 lines
2.1 KiB
Ruby
66 lines
2.1 KiB
Ruby
module Travis::API::V3
|
|
class Renderer::ModelRenderer
|
|
PRIMITIVE = [String, Symbol, Numeric, true, false, nil]
|
|
private_constant :PRIMITIVE
|
|
|
|
def self.type(type = nil)
|
|
@type = type if type
|
|
@type = name[/[^:]+$/].underscore.to_sym unless defined? @type # allows setting type to nil
|
|
@type
|
|
end
|
|
|
|
def self.representation(name, *fields)
|
|
fields.each { |field| class_eval "def #{field}; @model.#{field}; end" unless method_defined?(field) }
|
|
representations[name] = fields
|
|
end
|
|
|
|
def self.representations
|
|
@representations ||= {}
|
|
end
|
|
|
|
def self.render(model, representation = :standard, **options)
|
|
new(model, **options).render(representation)
|
|
end
|
|
|
|
attr_reader :model, :options, :script_name
|
|
attr_writer :href
|
|
|
|
def initialize(model, script_name: nil, **options)
|
|
@model = model
|
|
@options = options
|
|
@script_name = script_name
|
|
end
|
|
|
|
def href
|
|
return @href if defined? @href # allows setting href to nil
|
|
return unless self.class.type and model.respond_to? :attributes
|
|
@href = Renderer.href(self.class.type, model.attributes, script_name: script_name)
|
|
end
|
|
|
|
def render(representation)
|
|
result = {}
|
|
result[:@type] = self.class.type if self.class.type
|
|
result[:@href] = href if href
|
|
fields = self.class.representations.fetch(representation)
|
|
|
|
fields.each { |field| result[field] = render_value(send(field)) }
|
|
result
|
|
end
|
|
|
|
def render_model(model, type: model.class.name[/[^:]+$/].to_sym, mode: :minimal, **options)
|
|
Renderer[type].render(model, mode, script_name: script_name, **options)
|
|
end
|
|
|
|
def render_value(value)
|
|
case value
|
|
when Hash then value.map { |k, v| [k, render_value(v)] }.to_h
|
|
when Array then value.map { |v | render_value(v) }
|
|
when *PRIMITIVE then value
|
|
when Time then value.strftime('%Y-%m-%dT%H:%M:%SZ')
|
|
when Model then render_model(value)
|
|
else raise ArgumentError, 'cannot render %p (%p)' % [value.class, value]
|
|
end
|
|
end
|
|
end
|
|
end
|