Class: Shale::Mapper

Inherits:
Type::Complex show all
Defined in:
lib/shale/mapper.rb

Overview

Base class used for mapping

Examples:

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

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Type::Complex

as_xml, from_csv, from_json, from_toml, from_xml, from_yaml, of_xml, to_csv, #to_csv, #to_hash, #to_json, to_json, to_toml, #to_toml, to_xml, #to_xml, to_yaml, #to_yaml

Methods inherited from Type::Value

as_csv, as_hash, as_json, as_toml, as_xml, as_xml_value, as_yaml, cast, of_csv, of_hash, of_json, of_toml, of_xml, of_yaml

Constructor Details

#initialize(**props) ⇒ Mapper

Initialize instance with properties

Examples:

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">>

Parameters:

  • props (Hash)

    Properties

Raises:



363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
# File 'lib/shale/mapper.rb', line 363

def initialize(**props)
  super()

  unless props.empty?
    unknown_attributes = props.keys - self.class.attributes.keys

    unless unknown_attributes.empty?
      raise UnknownAttributeError.new(self.class.to_s, unknown_attributes[0].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

    send(attribute.setter, value)
  end
end

Class Attribute Details

.attributesHash<Symbol, Shale::Attribute> (readonly)

Return attributes Hash

Returns:



61
62
63
# File 'lib/shale/mapper.rb', line 61

def attributes
  @attributes
end

.csv_mappingShale::Mapping::Dict (readonly)

Return CSV mapping object



96
97
98
# File 'lib/shale/mapper.rb', line 96

def csv_mapping
  @csv_mapping
end

.hash_mappingShale::Mapping::Dict (readonly)

Return Hash mapping object



68
69
70
# File 'lib/shale/mapper.rb', line 68

def hash_mapping
  @hash_mapping
end

.json_mappingShale::Mapping::Dict (readonly)

Return JSON mapping object



75
76
77
# File 'lib/shale/mapper.rb', line 75

def json_mapping
  @json_mapping
end

.toml_mappingShale::Mapping::Dict (readonly)

Return TOML mapping object



89
90
91
# File 'lib/shale/mapper.rb', line 89

def toml_mapping
  @toml_mapping
end

.xml_mappingShale::Mapping::XML (readonly)

Return XML mapping object

Returns:

  • (Shale::Mapping::XML)


103
104
105
# File 'lib/shale/mapper.rb', line 103

def xml_mapping
  @xml_mapping
end

.yaml_mappingShale::Mapping::Dict (readonly)

Return YAML mapping object



82
83
84
# File 'lib/shale/mapper.rb', line 82

def yaml_mapping
  @yaml_mapping
end

Class Method Details

.attribute(name, type, collection: false, default: nil) ⇒ Object

Define attribute on class

Examples:

class 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']

Parameters:

  • name (Symbol)

    Name of the attribute

  • type (Shale::Type::Value)

    Type of the attribute

  • collection (Boolean) (defaults to: false)

    Is the attribute a collection

  • default (Proc) (defaults to: nil)

    Default value for the attribute

Raises:



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/shale/mapper.rb', line 173

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) unless @hash_mapping.finalized?
  @json_mapping.map(name.to_s, to: name) unless @json_mapping.finalized?
  @yaml_mapping.map(name.to_s, to: name) unless @yaml_mapping.finalized?
  @toml_mapping.map(name.to_s, to: name) unless @toml_mapping.finalized?
  @csv_mapping.map(name.to_s, to: name) unless @csv_mapping.finalized?
  @xml_mapping.map_element(name.to_s, to: name) unless @xml_mapping.finalized?

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

    def #{name}=(val)
      @#{name} = #{collection} ? val : #{type}.cast(val)
    end
  RUBY
end

.csv(&block) ⇒ Object

Define CSV mapping

Examples:

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

  csv do
    map 'first_name', to: :first_name
    map 'last_name', to: :last_name
    map 'age', to: :age
  end
end

Parameters:

  • block (Proc)


312
313
314
315
316
# File 'lib/shale/mapper.rb', line 312

def csv(&block)
  @csv_mapping = @__csv_mapping_init.dup
  @csv_mapping.finalize!
  @csv_mapping.instance_eval(&block)
end

.hsh(&block) ⇒ Object

Define Hash mapping

Examples:

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

  hsh do
    map 'firstName', to: :first_name
    map 'lastName', to: :last_name
    map 'age', to: :age
  end
end

Parameters:

  • block (Proc)


216
217
218
219
220
# File 'lib/shale/mapper.rb', line 216

def hsh(&block)
  @hash_mapping = @__hash_mapping_init.dup
  @hash_mapping.finalize!
  @hash_mapping.instance_eval(&block)
end

.inherited(subclass) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/shale/mapper.rb', line 106

def inherited(subclass)
  super

  attributes_module = Module.new
  subclass.instance_variable_set('@attributes_module', attributes_module)
  subclass.include(attributes_module)

  subclass.instance_variable_set('@model', subclass)
  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('@__toml_mapping_init', @toml_mapping.dup)
  subclass.instance_variable_set('@__csv_mapping_init', @csv_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)
  subclass.instance_variable_set('@toml_mapping', @toml_mapping.dup)
  subclass.instance_variable_set('@csv_mapping', @csv_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) ⇒ Object

Define JSON mapping

Examples:

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

  json do
    map 'firstName', to: :first_name
    map 'lastName', to: :last_name
    map 'age', to: :age
  end
end

Parameters:

  • block (Proc)


240
241
242
243
244
# File 'lib/shale/mapper.rb', line 240

def json(&block)
  @json_mapping = @__json_mapping_init.dup
  @json_mapping.finalize!
  @json_mapping.instance_eval(&block)
end

.model(klass = nil) ⇒ Object



135
136
137
138
139
140
141
142
# File 'lib/shale/mapper.rb', line 135

def model(klass = nil)
  if klass
    @model = klass
    xml_mapping.root(Utils.underscore(@model.name))
  else
    @model
  end
end

.toml(&block) ⇒ Object

Define TOML mapping

Examples:

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

  toml do
    map 'first_name', to: :first_name
    map 'last_name', to: :last_name
    map 'age', to: :age
  end
end

Parameters:

  • block (Proc)


288
289
290
291
292
# File 'lib/shale/mapper.rb', line 288

def toml(&block)
  @toml_mapping = @__toml_mapping_init.dup
  @toml_mapping.finalize!
  @toml_mapping.instance_eval(&block)
end

.xml(&block) ⇒ Object

Define XML mapping

Examples:

class 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

Parameters:

  • block (Proc)


337
338
339
340
341
342
# File 'lib/shale/mapper.rb', line 337

def xml(&block)
  @xml_mapping = @__xml_mapping_init.dup
  @xml_mapping.finalize!
  @xml_mapping.root('')
  @xml_mapping.instance_eval(&block)
end

.yaml(&block) ⇒ Object

Define YAML mapping

Examples:

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

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

Parameters:

  • block (Proc)


264
265
266
267
268
# File 'lib/shale/mapper.rb', line 264

def yaml(&block)
  @yaml_mapping = @__yaml_mapping_init.dup
  @yaml_mapping.finalize!
  @yaml_mapping.instance_eval(&block)
end