class Serial::HashBuilder

A builder for building hashes. You most likely just want to look at the public API methods in this class.

Public Class Methods

new(context) click to toggle source

@api private

# File lib/serial/hash_builder.rb, line 6
def initialize(context)
  @context = context
  @data = {}
end

Public Instance Methods

attribute(key, value = nil, &block) click to toggle source

@api public Declare an attribute.

@example without block

h.attribute(:id, 5) # => { "id" => 5 }

@example nested attribute, with block

h.attribute(:project, project) do |h, project|
  h.attribute(:name, project.name)
end # => { "project" => { "name" => … } }

@param key [#to_s] @param value @yield [builder, value] declare nested attribute if block is given @yieldparam builder [HashBuilder] (keep in mind the examples shadow the outer `h` variable) @yieldparam value @raise [DuplicateKeyError] if the same key has already been defined.

# File lib/serial/hash_builder.rb, line 28
def attribute(key, value = nil, &block)
  check_duplicate_key!(key)
  attribute!(key, value, &block)
end
attribute!(key, value = nil, &block) click to toggle source

@api public Same as {#attribute}, but will not raise an error on duplicate keys.

@see attribute @param (see attribute) @yield (see attribute) @yieldparam (see attribute)

# File lib/serial/hash_builder.rb, line 40
def attribute!(key, value = nil, &block)
  value = HashBuilder.build(@context, value, &block) if block
  @data[key.to_s] = value
end
collection(key, &block) click to toggle source

@api public Declare a collection attribute. This is a low-level method, see {#map} instead.

@example

h.collection(:people) do |l|
  l.element do |h|
    h.attribute()
  end
  l.element do |h|
    h.attribute()
  end
  l.collection do |l|
    l.element do |h|
      h.attribute()
    end
  end
end # => { "people" => [{…}, {…}, [{…}]] }

@see ArrayBuilder @param key [#to_s] @yield [builder] @yieldparam builder [ArrayBuilder]

# File lib/serial/hash_builder.rb, line 67
def collection(key, &block)
  check_duplicate_key!(key)
  collection!(key, &block)
end
collection!(key, &block) click to toggle source

@api public Same as {#collection}, but will not raise an error on duplicate keys.

@see collection @param (see collection) @yield (see collection) @yieldparam (see collection)

# File lib/serial/hash_builder.rb, line 79
def collection!(key, &block)
  attribute!(key, ArrayBuilder.build(@context, &block))
end
map(key, list, &block) click to toggle source

@api public Declare a collection attribute from a list of values.

@example

h.map(:people, project.people) do |h, person|
  h.attribute(:name, person.name)
end # => { "people" => [{ "name" => … }] }

@see collection @param key [#to_s] @param list [#each] @yield [builder, value] yields each value from list to build an array of hashes @yieldparam builder [HashBuilder] @yieldparam value

# File lib/serial/hash_builder.rb, line 97
def map(key, list, &block)
  check_duplicate_key!(key)
  map!(key, list, &block)
end
map!(key, list, &block) click to toggle source

@api public Same as {#map}, but will not raise an error on duplicate keys.

@see map @param (see map) @yield (see map) @yieldparam (see map)

# File lib/serial/hash_builder.rb, line 109
def map!(key, list, &block)
  collection!(key) do |builder|
    list.each do |item|
      builder.element do |element|
        element.exec(item, &block)
      end
    end
  end
end
merge(value, &serializer) click to toggle source

@api public Merge another serializer into the current serialization.

@example

ExtendedProjectSerializer = Serial::Serializer.new do |h, project|
  h.merge(project, &ProjectSerializer)
  h.attribute(:extra, project.extra_info)
end # => { "name" => …, …, "extra" => … }

@param value @yield [builder, value] to another serializer @yieldparam builder [HashBuilder] @yieldparam value @raise [DuplicateKeyError] if a key to be merged is already defined.

# File lib/serial/hash_builder.rb, line 133
def merge(value, &serializer)
  hash = HashBuilder.build(@context, value, &serializer)
  hash.keys.each { |key| check_duplicate_key!(key) }
  @data.merge!(hash)
end
merge!(value, &serializer) click to toggle source

@api public Same as {#merge}, but will not raise an error on duplicate keys.

@see merge @param (see merge) @yield (see merge) @yieldparam (see merge)

# File lib/serial/hash_builder.rb, line 146
def merge!(value, &serializer)
  hash = HashBuilder.build(@context, value, &serializer)
  @data.merge!(hash)
end

Private Instance Methods

check_duplicate_key!(key) click to toggle source

@param key [#to_s] @raise [DuplicateKeyError] if key is defined @return [nil]

# File lib/serial/hash_builder.rb, line 156
def check_duplicate_key!(key)
  if @data.has_key?(key.to_s)
    raise DuplicateKeyError, "'#{key}' is already defined"
  end
end