lib/dm-serializer/to_yaml.rb in dm-serializer-1.1.0 vs lib/dm-serializer/to_yaml.rb in dm-serializer-1.2.0.rc1

- old
+ new

@@ -1,69 +1,160 @@ require 'dm-serializer/common' module DataMapper module Serializer + TAG_NAME = "ruby/DataMapper,#{DataMapper::VERSION}".freeze + + # Include a callback to register the YAML output + # + # @param [DataMapper::Model] descendant + # + # @return [undefined] + # + # @api private + def self.included(descendant) + YAML.add_domain_type(TAG_NAME, descendant.name) do |_tag, values| + values + end + end + # Serialize a Resource to YAML # - # @return [YAML] - # A YAML representation of this Resource. - def to_yaml(opts_or_emitter = {}) - unless opts_or_emitter.is_a?(Hash) - emitter = opts_or_emitter - opts = {} - else - emitter = {} - opts = opts_or_emitter + # @example + # yaml = resource.to_yaml # => a valid YAML string + # + # @param [Hash] options + # + # @return [String] + # + # @api public + def to_yaml(options = {}) + YAML.quick_emit(object_id, options) do |out| + out.map(to_yaml_type, to_yaml_style) do |map| + encode_with(map, options.kind_of?(Hash) ? options : {}) + end end + end unless YAML.const_defined?(:ENGINE) && !YAML::ENGINE.syck? - YAML.quick_emit(object_id,emitter) do |out| - out.map(nil,to_yaml_style) do |map| - properties_to_serialize(opts).each do |property| - value = __send__(property.name.to_sym) - map.add(property.name, value.is_a?(Class) ? value.to_s : value) - end + # A callback to encode the resource in the YAML stream + # + # @param [#add] coder + # handles adding the values to the output + # + # @param [Hash] options + # optional Hash configuring the output + # + # @return [undefined] + # + # @api public + def encode_with(coder, options = {}) + coder.tag = to_yaml_type if coder.respond_to?(:tag=) + coder.style = to_yaml_style if coder.respond_to?(:style=) - # add methods - Array(opts[:methods]).each do |meth| - if respond_to?(meth) - map.add(meth.to_sym, __send__(meth)) - end - end + methods = [] - if (additions = instance_variable_get("@yaml_addes")) - additions.each { |k,v| map.add(k.to_s,v) } - end - end + methods.concat properties_to_serialize(options).map { |property| property.name } + methods.concat Array(options[:methods]) + + methods.each do |method| + coder.add(method.to_s, __send__(method)) end end + private + + # Return the YAML type to use for the output + # + # @return [String] + # + # @api private + def to_yaml_type + "!#{TAG_NAME}:#{model.name}" + end + + # Return the YAML style to use for the output + # + # @return [Integer] + # + # @api private + def to_yaml_style + Psych::Nodes::Mapping::ANY + end if YAML.const_defined?(:ENGINE) && YAML::ENGINE.yamler == 'psych' + module ValidationErrors module ToYaml + + # Serialize the errors to YAML + # + # @example + # yaml = errors.to_yaml # => a valid YAML string + # + # @param [Hash] options + # + # @return [String] + # + # @api public def to_yaml(*args) - DataMapper::Ext::Array.to_hash(errors).to_yaml(*args) + Hash[errors].to_yaml(*args) end - end - end - end + # A callback to encode the errors in the YAML stream + # + # @param [#add] coder + # handles adding the values to the output + # + # @return [undefined] + # + # @api public + def encode_with(coder) + coder.map = Hash[errors] + end - class Collection - def to_yaml(opts_or_emitter = {}) - unless opts_or_emitter.is_a?(Hash) - to_a.to_yaml(opts_or_emitter) - else - # FIXME: Don't double handle the YAML (remove the YAML.load) - to_a.collect { |x| YAML.load(x.to_yaml(opts_or_emitter)) }.to_yaml - end - end - end + end # module ToYaml + end # module ValidationErrors - if Serializer.dm_validations_loaded? + module Collection + module ToYaml + # Serialize the collection to YAML + # + # @example + # yaml = collection.to_yaml # => a valid YAML string + # + # @param [Hash] options + # + # @return [String] + # + # @api public + def to_yaml(*args) + to_a.to_yaml(*args) + end + + # A callback to encode the collection in the YAML stream + # + # @param [#add] coder + # handles adding the values to the output + # + # @return [undefined] + # + # @api public + def encode_with(coder) + coder.seq = to_a + end + + end # module ToYaml + end # module Collection + end # module Serializer + + class Collection + include Serializer::Collection::ToYaml + end # class Collection + + if const_defined?(:Validations) module Validations class ValidationErrors include DataMapper::Serializer::ValidationErrors::ToYaml - end - end - + end # class ValidationErrors + end # module Validations end -end + +end # module DataMapper