JSONAPI.Utils.String (jsonapi v1.13.1)

Copy Markdown View Source

String manipulation helpers.

Summary

Functions

Replace underscores or dashes between words in value with camelCasing

Replace underscores between words in value with dashes

Like JSONAPI.Utils.String.expand_fields/2, but only uses the given function to transform the keys of a top-level map. Other values are transformed with to_string/1.

The configured transformation for the API's fields. JSON:API v1.1 recommends using camlized fields (e.g. "goodDog", versus "good_dog"). However, we don't hold a strong opinion, so feel free to customize it how you would like (e.g. "good-dog", versus "good_dog").

Replace dashes between words in value with underscores

Functions

camelize(value)

@spec camelize(atom()) :: String.t()
@spec camelize(String.t()) :: String.t()

Replace underscores or dashes between words in value with camelCasing

Ignores underscores or dashes that are not between letters/numbers

Examples

iex> camelize("top_posts")
"topPosts"

iex> camelize(:top_posts)
"topPosts"

iex> camelize("_top_posts")
"_topPosts"

iex> camelize("_top__posts_")
"_top__posts_"

iex> camelize("")
""

iex> camelize("alreadyCamelized")
"alreadyCamelized"

iex> camelize("alreadyCamelized-id")
"alreadyCamelizedId"

iex> camelize("alreadyCamelized_id")
"alreadyCamelizedId"

iex> camelize("PascalLambda_id")
"pascalLambdaId"

dasherize(value)

@spec dasherize(atom()) :: String.t()
@spec dasherize(String.t()) :: String.t()

Replace underscores between words in value with dashes

Ignores underscores that are not between letters/numbers

Examples

iex> dasherize("top_posts")
"top-posts"

iex> dasherize("_top_posts")
"_top-posts"

iex> dasherize("_top__posts_")
"_top__posts_"

iex> dasherize("ages_0_17")
"ages-0-17"

expand_fields(value, fun)

@spec expand_fields(map(), function()) :: map()
@spec expand_fields(list(), function()) :: list()
@spec expand_fields(tuple(), function()) :: tuple()
@spec expand_fields(String.t() | atom(), function()) :: String.t()

Examples

iex> expand_fields(%{"foo-bar" => "baz"}, &underscore/1)
%{"foo_bar" => "baz"}

iex> expand_fields(%{"foo_bar" => "baz"}, &dasherize/1)
%{"foo-bar" => "baz"}

iex> expand_fields(%{"foo-bar" => "baz"}, &camelize/1)
%{"fooBar" => "baz"}

iex> expand_fields({"foo-bar", "dollar-sol"}, &underscore/1)
{"foo_bar", "dollar-sol"}

iex> expand_fields({"foo-bar", %{"a-d" => "z-8"}}, &underscore/1)
{"foo_bar", %{"a_d" => "z-8"}}

iex> expand_fields(%{"f-b" => %{"a-d" => "z"}, "c-d" => "e"}, &underscore/1)
%{"f_b" => %{"a_d" => "z"}, "c_d" => "e"}

iex> expand_fields(%{"f-b" => %{"a-d" => %{"z-w" => "z"}}, "c-d" => "e"}, &underscore/1)
%{"f_b" => %{"a_d" => %{"z_w" => "z"}}, "c_d" => "e"}

iex> expand_fields(:"foo-bar", &underscore/1)
"foo_bar"

iex> expand_fields(:foo_bar, &dasherize/1)
"foo-bar"

iex> expand_fields(:"foo-bar", &camelize/1)
"fooBar"

iex> expand_fields(%{"f-b" => "a-d"}, &underscore/1)
%{"f_b" => "a-d"}

iex> expand_fields(%{"inserted-at" => ~N[2019-01-17 03:27:24.776957]}, &underscore/1)
%{"inserted_at" => ~N[2019-01-17 03:27:24.776957]}

iex> expand_fields(%{"xValue" => 123}, &underscore/1)
%{"x_value" => 123}

iex> expand_fields(%{"attributes" => %{"corgiName" => "Wardel"}}, &underscore/1)
%{"attributes" => %{"corgi_name" => "Wardel"}}

iex> expand_fields(%{"attributes" => %{"corgiName" => ["Wardel"]}}, &underscore/1)
%{"attributes" => %{"corgi_name" => ["Wardel"]}}

iex> expand_fields(%{"attributes" => %{"someField" => ["SomeValue", %{"nestedField" => "Value"}]}}, &underscore/1)
%{"attributes" => %{"some_field" => ["SomeValue", %{"nested_field" => "Value"}]}}

iex> expand_fields([%{"fooBar" => "a"}, %{"fooBar" => "b"}], &underscore/1)
[%{"foo_bar" => "a"}, %{"foo_bar" => "b"}]

iex> expand_fields([%{"foo_bar" => "a"}, %{"foo_bar" => "b"}], &camelize/1)
[%{"fooBar" => "a"}, %{"fooBar" => "b"}]

iex> expand_fields(%{"fooAttributes" => [%{"fooBar" => "a"}, %{"fooBar" => "b"}]}, &underscore/1)
%{"foo_attributes" => [%{"foo_bar" => "a"}, %{"foo_bar" => "b"}]}

iex> expand_fields(%{"foo_attributes" => [%{"foo_bar" => "a"}, %{"foo_bar" => "b"}]}, &camelize/1)
%{"fooAttributes" => [%{"fooBar" => "a"}, %{"fooBar" => "b"}]}

iex> expand_fields(%{"foo_attributes" => [%{"foo_bar" => [1, 2]}]}, &camelize/1)
%{"fooAttributes" => [%{"fooBar" => [1, 2]}]}

expand_root_keys(map, fun)

Like JSONAPI.Utils.String.expand_fields/2, but only uses the given function to transform the keys of a top-level map. Other values are transformed with to_string/1.

Examples

iex> expand_root_keys(%{"foo-bar" => %{"bar-baz" => "x"}}, &underscore/1)
%{"foo_bar" => %{"bar-baz" => "x"}}

iex> expand_root_keys(%{"foo-bar" => [:x, %{"bar-baz" => "y"}]}, &underscore/1)
%{"foo_bar" => ["x", %{"bar-baz" => "y"}]}

field_transformation()

The configured transformation for the API's fields. JSON:API v1.1 recommends using camlized fields (e.g. "goodDog", versus "good_dog"). However, we don't hold a strong opinion, so feel free to customize it how you would like (e.g. "good-dog", versus "good_dog").

This library currently supports camelized, dashed and underscored fields. Shallow variants exist that only transform top-level field keys.

Configuration examples

camelCase fields:

config :jsonapi, field_transformation: :camelize
config :jsonapi, field_transformation: :camelize_shallow

Dashed fields:

config :jsonapi, field_transformation: :dasherize
config :jsonapi, field_transformation: :dasherize_shallow

Underscored fields:

config :jsonapi, field_transformation: :underscore

underscore(value)

@spec underscore(String.t()) :: String.t()
@spec underscore(atom()) :: String.t()

Replace dashes between words in value with underscores

Ignores dashes that are not between letters/numbers

Examples

iex> underscore("top-posts")
"top_posts"

iex> underscore(:top_posts)
"top_posts"

iex> underscore("-top-posts")
"-top_posts"

iex> underscore("-top--posts-")
"-top--posts-"

iex> underscore("corgiAge")
"corgi_age"

iex> underscore("ages-0-17")
"ages_0_17"