Another option is to use Nestru. It supports transformation in both ways. Encoding from nested struct into a map can be like the following.
defmodule Nadia.Model.Chat do
@derive Nestru.Encoder
defstruct [:first_name, :id, :last_name, :photo, :title, :type, :username]
end
defmodule Nadia.Model.User do
@derive Nestru.Encoder
defstruct [:first_name, :id, :last_name, :username]
end
defmodule Nadia.Model.Message do
@derive Nestru.Encoder
defstruct [
:audio,
:caption,
:channel_chat_created,
:chat,
:contact,
:date,
:delete_chat_photo,
:document,
:edit_date,
:entities,
:forward_date,
:forward_from,
:forward_from_chat,
:from,
:group_chat_created,
:left_chat_member,
:location,
:message_id,
:migrate_from_chat_id,
:migrate_to_chat_id,
:new_chat_member,
:new_chat_photo,
:new_chat_title,
:photo,
:pinned_message,
:reply_to_message,
:sticker,
:supergroup_chat_created,
:text,
:venue,
:video,
:voice
]
end
struct = %{
callback_query: nil,
channel_post: nil,
chosen_inline_result: nil,
edited_message: nil,
inline_query: nil,
message: %Nadia.Model.Message{
audio: nil,
caption: nil,
channel_chat_created: nil,
chat: %Nadia.Model.Chat{
first_name: "Christian",
id: 543211234,
last_name: "Tovar",
photo: nil,
title: nil,
type: "private",
username: "ChristianTovar"
},
contact: nil,
date: 1562605521,
delete_chat_photo: nil,
document: nil,
edit_date: nil,
entities: nil,
forward_date: nil,
forward_from: nil,
forward_from_chat: nil,
from: %Nadia.Model.User{
first_name: "Christian",
id: 543211234,
last_name: "Tovar",
username: "ChristianTovar"
},
group_chat_created: nil,
left_chat_member: nil,
location: nil,
message_id: 714,
migrate_from_chat_id: nil,
migrate_to_chat_id: nil,
new_chat_member: nil,
new_chat_photo: [],
new_chat_title: nil,
photo: [],
pinned_message: nil,
reply_to_message: nil,
sticker: nil,
supergroup_chat_created: nil,
text: "google meets",
venue: nil,
video: nil,
voice: nil
},
update_id: 412827321
}
encoding looks like:
iex> Nestru.to_map(struct)
{:ok,
%{
callback_query: nil,
channel_post: nil,
chosen_inline_result: nil,
edited_message: nil,
inline_query: nil,
message: %{
audio: nil,
caption: nil,
channel_chat_created: nil,
chat: %{
first_name: "Christian",
id: 543211234,
last_name: "Tovar",
photo: nil,
title: nil,
type: "private",
username: "ChristianTovar"
},
contact: nil,
date: 1562605521,
delete_chat_photo: nil,
document: nil,
edit_date: nil,
entities: nil,
forward_date: nil,
forward_from: nil,
forward_from_chat: nil,
from: %{first_name: "Christian", id: 543211234, last_name: "Tovar", username: "ChristianTovar"},
group_chat_created: nil,
left_chat_member: nil,
location: nil,
message_id: 714,
migrate_from_chat_id: nil,
migrate_to_chat_id: nil,
new_chat_member: nil,
new_chat_photo: [],
new_chat_title: nil,
photo: [],
pinned_message: nil,
reply_to_message: nil,
sticker: nil,
supergroup_chat_created: nil,
text: "google meets",
venue: nil,
video: nil,
voice: nil
},
update_id: 412827321
}}