Current section
Files
Jump to
Current section
Files
lib/gemini/utils/map_helpers.ex
defmodule Gemini.Utils.MapHelpers do
@moduledoc """
Shared helper functions for building maps with optional values.
These helpers are used throughout the codebase to conditionally add
key-value pairs to maps, skipping nil values.
"""
@doc """
Conditionally puts a value into a map if the value is not nil.
## Examples
iex> MapHelpers.maybe_put(%{a: 1}, :b, 2)
%{a: 1, b: 2}
iex> MapHelpers.maybe_put(%{a: 1}, :b, nil)
%{a: 1}
"""
@spec maybe_put(map(), any(), any()) :: map()
def maybe_put(map, _key, nil), do: map
def maybe_put(map, key, value), do: Map.put(map, key, value)
@doc """
Conditionally puts a value into a map if the value is not nil or empty string.
Useful when building credential maps where empty strings should be treated as missing.
## Examples
iex> MapHelpers.maybe_put_non_empty(%{a: 1}, :b, "value")
%{a: 1, b: "value"}
iex> MapHelpers.maybe_put_non_empty(%{a: 1}, :b, "")
%{a: 1}
iex> MapHelpers.maybe_put_non_empty(%{a: 1}, :b, nil)
%{a: 1}
"""
@spec maybe_put_non_empty(map(), any(), any()) :: map()
def maybe_put_non_empty(map, _key, nil), do: map
def maybe_put_non_empty(map, _key, ""), do: map
def maybe_put_non_empty(map, key, value), do: Map.put(map, key, value)
@doc """
Conditionally puts a value into a map if the value is not nil or zero.
Useful when building request maps where zero values should be omitted.
## Examples
iex> MapHelpers.maybe_put_non_zero(%{a: 1}, :b, 5)
%{a: 1, b: 5}
iex> MapHelpers.maybe_put_non_zero(%{a: 1}, :b, 0)
%{a: 1}
iex> MapHelpers.maybe_put_non_zero(%{a: 1}, :b, nil)
%{a: 1}
"""
@spec maybe_put_non_zero(map(), any(), any()) :: map()
def maybe_put_non_zero(map, _key, nil), do: map
def maybe_put_non_zero(map, _key, 0), do: map
def maybe_put_non_zero(map, key, value), do: Map.put(map, key, value)
@doc """
Builds a path with pagination query parameters.
Takes a base path and options keyword list, extracting standard pagination
params (:page_size, :page_token, :filter) and building the full path.
## Examples
iex> MapHelpers.build_paginated_path("batches", [page_size: 10])
"batches?pageSize=10"
iex> MapHelpers.build_paginated_path("files", [])
"files"
iex> MapHelpers.build_paginated_path("operations", [page_size: 20, page_token: "abc", filter: "state=ACTIVE"])
"operations?pageSize=20&pageToken=abc&filter=state%3DACTIVE"
"""
@spec build_paginated_path(String.t(), keyword()) :: String.t()
def build_paginated_path(base_path, opts) do
query_params =
[]
|> add_query_param("pageSize", Keyword.get(opts, :page_size))
|> add_query_param("pageToken", Keyword.get(opts, :page_token))
|> add_query_param("filter", Keyword.get(opts, :filter))
case query_params do
[] -> base_path
params -> "#{base_path}?#{URI.encode_query(params)}"
end
end
@doc """
Adds a query parameter to a list if the value is not nil.
## Examples
iex> MapHelpers.add_query_param([], "pageSize", 10)
[{"pageSize", 10}]
iex> MapHelpers.add_query_param([{"a", 1}], "b", nil)
[{"a", 1}]
"""
@spec add_query_param(list(), String.t(), any()) :: list()
def add_query_param(params, _key, nil), do: params
def add_query_param(params, key, value), do: [{key, value} | params]
end