Module: Docker::API::Body

Defined in:
lib/docker/api/body.rb

Overview

Builds request bodies without making callers shout in PascalCase.

Class Method Summary collapse

Class Method Details

.build(attributes) ⇒ Hash

Convert top-level snake_case keys to the PascalCase the daemon uses.

Only the top level is converted, deliberately. Nested structures are passed through exactly as given, because their keys are frequently data rather than field names -- Labels, ExposedPorts, PortBindings and Sysctls are all maps whose keys belong to the user. A recursive converter would mangle { "com.example/team" => "infra" } into something the daemon has never heard of.

Keys that already look like the daemon's own are left alone, so a body copied verbatim out of Docker's documentation keeps working.

Examples:

Body.build(image: "alpine", host_config: { "Binds" => ["/a:/b"] })
#=> { "Image" => "alpine", "HostConfig" => { "Binds" => ["/a:/b"] } }

Parameters:

  • attributes (Hash)

    a body in either convention

Returns:

  • (Hash)

    a body in the daemon's convention



30
31
32
33
34
# File 'lib/docker/api/body.rb', line 30

def build(attributes)
  (attributes || {}).each_with_object({}) do |(key, value), out|
    out[camelize(key)] = value unless value.nil?
  end
end

.camelize(key) ⇒ String

Returns the daemon's spelling of a field name.

Parameters:

  • key (String, Symbol)

Returns:

  • (String)

    the daemon's spelling of a field name



38
39
40
41
42
43
44
# File 'lib/docker/api/body.rb', line 38

def camelize(key)
  name = key.to_s
  # Already PascalCase, or a literal the caller means verbatim.
  return name if name.match?(/\A[A-Z]/)

  name.split("_").map { |part| part.sub(/\A(.)/) { Regexp.last_match(1).upcase } }.join
end