RoboZoom

RoboZoom

Struct Data Transformations - best approach to simple data transformations?

New to elixir here - looking for help for the best approach to simple data transformations.

I have a config file that I need to transform slightly into a slightly different format to fit a service call. In essence, it looks like this:

defmodule AppConfig do
  @enforce_keys [:username, :endpoints]
  defstruct username: "",
            password: "",
            endpoints: "",
            stacktrace: false,
            show_sensitive_data_on_connection_error: false,
            pool_size: 10,
            database: ""
end

defmodule DatabaseConfig do
  alias DatabaseUserConfig

  @type t() :: %__MODULE__{
          name: String.t(),
          users: DatabaseUserConfig.t(),
          options: any()
        }
  @enforce_keys [:name]
  defstruct [:name, :users, :options]
end

defmodule DatabaseUserConfig do
  @type t() :: %__MODULE__{
          username: String.t(),
          passwd: String.t(),
        }

  @enforce_keys [:username]
  defstruct [:username, :passwd]
end

I need to translate AppConfig into DatabaseConfig. Ideally, I’d like to do this in a way so that if I change options, I don’t need to redo this function.

Looking at other libraries, it appears as if the normal way to do this would be to create new function for DatabaseConfig and pass AppConfig as an argument, then inside that function I’d manually assign each property:

def new(app_config) do 
  %DatabaseConfig{ name: app_config.database, users: [%User{name: app_config.name, password: app_config.password], options: %{...}]
end

If I filled out options manually, every time I changed the options format in one place or the other, I’d have to redo this function (and any tests with this of course). Is there a way to do the formatting that I know that I need to do, and pass through everything else?

Marked As Solved

kip

kip

ex_cldr Core Team

Maybe something like this, that uses Map.split/2 to split the map in two?

def new(%AppConfig{} = app_config) do 
  {config, options} = Map.split(app_config, [:name, :password, :database])
  
  %DatabaseConfig{ name: config.database, users: [%User{name: config.name, password: config.password], options: options]
end

Where Next?

Popular in Questions Top

sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
makeitrein
Hey all, just started picking up Elixir last week and am writing a scraper as a learning project. Baby step #1 is extracting the number ...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
sabri
Can someone explain the settings of pool_size of Ecto in config file? and what is the recommend size? Thanks
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

Other popular topics Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New

We're in Beta

About us Mission Statement