Bonfire.API.MastoCompat.Helpers (Bonfire v1.0.1-social-alpha.28)
View SourceShared helper functions for Mastodon API mappers.
This module provides common utilities used across mappers to safely extract and transform data from Bonfire structures to Mastodon format.
Summary
Functions
Recursively converts structs to JSON-safe values.
Formats a datetime to ISO8601 format as expected by Mastodon API.
Safely get a field from a map or struct, handling nil and NotLoaded associations.
Get the first non-nil value from a map by trying multiple keys in order.
Normalize a hashtag string for querying.
Converts a value to string, handling nil gracefully.
Validates an entity against a schema module and returns the valid entity or nil.
Functions
Recursively converts structs to JSON-safe values.
Handles DateTime, NaiveDateTime, Date, and Ecto NotLoaded associations. Can optionally filter out nil values and drop unknown struct types.
Options
:filter_nils- Remove nil values from maps and lists (default: false):drop_unknown_structs- Return nil for unrecognized structs instead of converting to map (default: false)
Examples
iex> deep_struct_to_map(%{date: ~U[2024-01-15 10:30:00Z]})
%{date: "2024-01-15T10:30:00Z"}
iex> deep_struct_to_map(%{value: nil}, filter_nils: true)
%{}
iex> deep_struct_to_map(%Ecto.Association.NotLoaded{})
nil
Formats a datetime to ISO8601 format as expected by Mastodon API.
Handles various datetime types (DateTime, NaiveDateTime, Date) and returns nil for invalid inputs.
Examples
iex> format_datetime(~U[2024-01-15 10:30:00Z])
"2024-01-15T10:30:00.000Z"
iex> format_datetime(nil)
nil
Safely get a field from a map or struct, handling nil and NotLoaded associations.
Returns nil for:
- nil input
- Empty maps
- NotLoaded Ecto associations
- Non-map inputs
- Missing keys
Examples
iex> get_field(%{name: "test"}, :name)
"test"
iex> get_field(nil, :name)
nil
iex> get_field(%{}, :name)
nil
iex> get_field(%{assoc: %Ecto.Association.NotLoaded{}}, :assoc)
nil
Get the first non-nil value from a map by trying multiple keys in order.
Useful when data can come from either GraphQL (with aliased field names) or directly from Ecto (with raw schema field names).
Examples
iex> get_fields(%{display_name: "Alice"}, [:display_name, :name])
"Alice"
iex> get_fields(%{name: "Bob"}, [:display_name, :name])
"Bob"
iex> get_fields(%{other: "value"}, [:display_name, :name])
nil
iex> get_fields(%{"avatar" => "url"}, [:avatar, "avatar", :icon, "icon"])
"url"
Normalize a hashtag string for querying.
Removes # prefix if present and handles case normalization. Uses Bonfire's hashtag normalization if available, otherwise falls back to simple lowercase.
Examples
iex> normalize_hashtag("#Bonfire")
"bonfire"
iex> normalize_hashtag("ELIXIR")
"elixir"
iex> normalize_hashtag(nil)
""
Converts a value to string, handling nil gracefully.
Examples
iex> to_string_safe(123)
"123"
iex> to_string_safe(nil)
nil
iex> to_string_safe("already_string")
"already_string"
Validates an entity against a schema module and returns the valid entity or nil.
Logs warnings for validation failures to aid debugging without crashing.
Parameters
entity- The map to validateschema_module- The schema module with avalidate/1function
Examples
iex> validate_and_return(%{"id" => "123"}, Schemas.Status)
%{"id" => "123", ...}
iex> validate_and_return(%{}, Schemas.Status)
nil # Logs warning about missing required fields