Moov.CaseConverter (Moov v1.0.0)

Copy Markdown View Source

Converts map keys between the snake_case Elixir developers expect and the camelCase JSON Moov's API speaks.

Moov.Client automatically applies to_camel_case/1 to every outgoing request body, so you can write idiomatic Elixir:

Moov.Accounts.create(client, %{
  account_type: "business",
  profile: %{business: %{legal_business_name: "Whole Body Fitness LLC"}}
})

and it is sent to Moov as:

{"accountType":"business","profile":{"business":{"legalBusinessName":"Whole Body Fitness LLC"}}}

Response bodies are returned with their keys untouched (camelCase strings, exactly as Moov sent them) to avoid surprising key collisions and to keep forward-compatibility with fields Moov adds in the future. Call to_snake_case/1 yourself if you'd like snake_case string keys on the way out, too.

Both functions:

  • recurse into nested maps and lists
  • leave struct values (DateTime, Date, etc.) untouched, so they keep being encoded by their own Jason.Encoder implementation
  • leave atom, number, boolean, nil, and binary leaf values untouched
  • only rewrite keys that are atoms or binaries - anything else (e.g. an integer key in a hand-built map) is left as-is

Summary

Functions

Deeply converts snake_case/camelCase-mixed map keys to camelCase strings, recursing into nested maps and lists. Struct values are passed through untouched.

The inverse of to_camel_case/1: deeply converts camelCase map keys to snake_case strings. Keys remain binaries (never atoms) so this is safe to run against untrusted, server-controlled response data without growing the atom table.

Functions

to_camel_case(value)

@spec to_camel_case(term()) :: term()

Deeply converts snake_case/camelCase-mixed map keys to camelCase strings, recursing into nested maps and lists. Struct values are passed through untouched.

Keys may be given as atoms or strings; the result always uses string keys (matching how Moov's JSON API + Jason work).

Examples

iex> Moov.CaseConverter.to_camel_case(%{legal_business_name: "Acme", address: %{postal_code: "80301"}})
%{"legalBusinessName" => "Acme", "address" => %{"postalCode" => "80301"}}

iex> Moov.CaseConverter.to_camel_case([%{first_name: "Ada"}])
[%{"firstName" => "Ada"}]

to_snake_case(value)

@spec to_snake_case(term()) :: term()

The inverse of to_camel_case/1: deeply converts camelCase map keys to snake_case strings. Keys remain binaries (never atoms) so this is safe to run against untrusted, server-controlled response data without growing the atom table.

Examples

iex> Moov.CaseConverter.to_snake_case(%{"accountID" => "abc", "displayName" => "Ada"})
%{"account_id" => "abc", "display_name" => "Ada"}