class Shale::Mapper

Base class used for mapping

@example

class Address < Shale::Mapper
  attribute :city, Shale::Type::String
  attribute :street, Shale::Type::String
  attribute :state, Shale::Type::Integer
  attribute :zip, Shale::Type::String
end

class Person < Shale::Mapper
  attribute :first_name, Shale::Type::String
  attribute :last_name, Shale::Type::String
  attribute :age, Shale::Type::Integer
  attribute :address, Address
end

person = Person.from_json(%{
  {
    "first_name": "John",
    "last_name": "Doe",
    "age": 55,
    "address": {
      "city": "London",
      "street": "Oxford Street",
      "state": "London",
      "zip": "E1 6AN"
    }
  }
})

person.to_json

@api public

Attributes

attributes[R]

Return attributes Hash

@return [Hash<Symbol, Shale::Attribute>]

@api public

hash_mapping[R]

Return Hash mapping object

@return [Shale::Mapping::KeyValue]

@api public

json_mapping[R]

Return JSON mapping object

@return [Shale::Mapping::KeyValue]

@api public

xml_mapping[R]

Return XML mapping object

@return [Shale::Mapping::XML]

@api public

yaml_mapping[R]

Return YAML mapping object

@return [Shale::Mapping::KeyValue]

@api public

Public Class Methods

attribute(name, type, collection: false, default: nil) click to toggle source

Define attribute on class

@param [Symbol] name Name of the attribute @param [Shale::Type::Base] type Type of the attribute @param [Boolean] collection Is the attribute a collection @param [Proc] default Default value for the attribute

@raise [DefaultNotCallableError] when attribute’s default is not callable

@example

calss Person < Shale::Mapper
  attribute :first_name, Shale::Type::String
  attribute :last_name, Shale::Type::String
  attribute :age, Shale::Type::Integer, default: -> { 1 }
  attribute :hobbies, Shale::Type::String, collection: true
end

person = Person.new

person.first_name # => nil
person.first_name = 'John'
person.first_name # => 'John'

person.age # => 1

person.hobbies << 'Dancing'
person.hobbies # => ['Dancing']

@api public

# File lib/shale/mapper.rb, line 137
      def attribute(name, type, collection: false, default: nil)
        name = name.to_sym

        unless default.nil? || default.respond_to?(:call)
          raise DefaultNotCallableError.new(to_s, name)
        end

        @attributes[name] = Attribute.new(name, type, collection, default)

        @hash_mapping.map(name.to_s, to: name)
        @json_mapping.map(name.to_s, to: name)
        @yaml_mapping.map(name.to_s, to: name)
        @xml_mapping.map_element(name.to_s, to: name)

        class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
          attr_reader :#{name}

          def #{name}=(val)
            @#{name} = #{collection} ? val : #{type}.cast(val)
          end
        RUBY
      end
hash(&block) click to toggle source

Define Hash mapping

@param [Proc] block

@example

calss Person < Shale::Mapper
  attribute :first_name, Shale::Type::String
  attribute :last_name, Shale::Type::String
  attribute :age, Shale::Type::Integer

  yaml do
    map 'firatName', to: :first_name
    map 'lastName', to: :last_name
    map 'age', to: :age
  end
end

@api public

# File lib/shale/mapper.rb, line 178
def hash(&block)
  @hash_mapping = @__hash_mapping_init.dup
  @hash_mapping.instance_eval(&block)
end
inherited(subclass) click to toggle source

@api private

Calls superclass method
# File lib/shale/mapper.rb, line 89
def inherited(subclass)
  super
  subclass.instance_variable_set('@attributes', @attributes.dup)

  subclass.instance_variable_set('@__hash_mapping_init', @hash_mapping.dup)
  subclass.instance_variable_set('@__json_mapping_init', @json_mapping.dup)
  subclass.instance_variable_set('@__yaml_mapping_init', @yaml_mapping.dup)
  subclass.instance_variable_set('@__xml_mapping_init', @xml_mapping.dup)

  subclass.instance_variable_set('@hash_mapping', @hash_mapping.dup)
  subclass.instance_variable_set('@json_mapping', @json_mapping.dup)
  subclass.instance_variable_set('@yaml_mapping', @yaml_mapping.dup)

  xml_mapping = @xml_mapping.dup
  xml_mapping.root(Utils.underscore(subclass.name || ''))

  subclass.instance_variable_set('@xml_mapping', xml_mapping.dup)
end
json(&block) click to toggle source

Define JSON mapping

@param [Proc] block

@example

calss Person < Shale::Mapper
  attribute :first_name, Shale::Type::String
  attribute :last_name, Shale::Type::String
  attribute :age, Shale::Type::Integer

  yaml do
    map 'firatName', to: :first_name
    map 'lastName', to: :last_name
    map 'age', to: :age
  end
end

@api public

# File lib/shale/mapper.rb, line 201
def json(&block)
  @json_mapping = @__json_mapping_init.dup
  @json_mapping.instance_eval(&block)
end
new(**props) click to toggle source

Initialize instance with properties

@param [Hash] props Properties

@raise [UnknownAttributeError] when attribute is not defined on the class

@example

Person.new(
  first_name: 'John',
  last_name: 'Doe',
  address: Address.new(city: 'London')
)
# => #<Person:0x00007f82768a2370
        @first_name="John",
        @last_name="Doe"
        @address=#<Address:0x00007fe9cf0f57d8 @city="London">>

@api public

Calls superclass method
# File lib/shale/mapper.rb, line 272
def initialize(**props)
  super()

  props.each_key do |name|
    unless self.class.attributes.keys.include?(name)
      raise UnknownAttributeError.new(self.class.to_s, name.to_s)
    end
  end

  self.class.attributes.each do |name, attribute|
    if props.key?(name)
      value = props[name]
    elsif attribute.default
      value = attribute.default.call
    end

    public_send("#{name}=", value)
  end
end
xml(&block) click to toggle source

Define XML mapping

@param [Proc] block

@example

calss Person < Shale::Mapper
  attribute :first_name, Shale::Type::String
  attribute :last_name, Shale::Type::String
  attribute :age, Shale::Type::Integer

  xml do
    root 'Person'
    map_content to: :first_name
    map_element 'LastName', to: :last_name
    map_attribute 'age', to: :age
  end
end

@api public

# File lib/shale/mapper.rb, line 248
def xml(&block)
  @xml_mapping = @__xml_mapping_init.dup
  @xml_mapping.instance_eval(&block)
end
yaml(&block) click to toggle source

Define YAML mapping

@param [Proc] block

@example

calss Person < Shale::Mapper
  attribute :first_name, Shale::Type::String
  attribute :last_name, Shale::Type::String
  attribute :age, Shale::Type::Integer

  yaml do
    map 'firat_name', to: :first_name
    map 'last_name', to: :last_name
    map 'age', to: :age
  end
end

@api public

# File lib/shale/mapper.rb, line 224
def yaml(&block)
  @yaml_mapping = @__yaml_mapping_init.dup
  @yaml_mapping.instance_eval(&block)
end