summaryrefslogtreecommitdiffhomepage
path: root/lib/axlsx/util/serialized_attributes.rb
blob: 5519f8431fa29a3f072d46c7bc937ce872cc7918 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
module Axlsx
  # This module allows us to define a list of symbols defining which
  # attributes will be serialized for a class.
  module SerializedAttributes

    # Extend with class methods
    def self.included(base)
      base.send :extend, ClassMethods
    end

    # class methods applied to all includers
    module ClassMethods

      # This is the method to be used in inheriting classes to specify 
      # which of the instance values are serializable
      def serializable_attributes(*symbols)
        @xml_attributes = symbols
      end

      # a reader for those attributes
      def xml_attributes
        @xml_attributes
      end

      # This helper registers the attributes that will be formatted as elements.
      def serializable_element_attributes(*symbols)
        @xml_element_attributes = symbols
      end

      # attr reader for element attributes
      def xml_element_attributes
        @xml_element_attributes
      end
    end

    # serializes the instance values of the defining object based on the 
    # list of serializable attributes.
    # @param [String] str The string instance to append this
    # serialization to.
    # @param [Hash] additional_attributes An option key value hash for
    # defining values that are not serializable attributes list.
    def serialized_attributes(str = '', additional_attributes = {})
      key_value_pairs = instance_values
      key_value_pairs.each do |key, value|
        key_value_pairs.delete(key) if value == nil
        key_value_pairs.delete(key) unless self.class.xml_attributes.include?(key.to_sym)
      end
      key_value_pairs.merge! additional_attributes
      key_value_pairs.each do |key, value|
        str << "#{Axlsx.camel(key, false)}=\"#{value}\" "
      end
      str
    end


    # serialized instance values at text nodes on a camelized element of the
    # attribute name. You may pass in a block for evaluation against non nil
    # values. We use an array for element attributes becuase misordering will
    # break the xml and 1.8.7 does not support ordered hashes.
    # @param [String] str The string instance to which serialized data is appended
    # @param [Array] additional_attributes An array of additional attribute names.
    # @param [Proc] block A which will be called with the value for each element.
    # @return [String] The serialized output.
    def serialized_element_attributes(str='', additional_attributes=[], &block)
      attrs = self.class.xml_element_attributes + additional_attributes
      values = instance_values
      attrs.each do |attribute_name|
        value = values[attribute_name.to_s]
        next if value.nil?
        value = yield value if block_given?
        element_name = Axlsx.camel(attribute_name, false)
        str << "<#{element_name}>#{value}</#{element_name}>"
      end
      str
    end
  end
end