Fl4m3Ph03n1x

Fl4m3Ph03n1x

Gradient does not recognize type of TypedStruct structures

Background

I have a module that uses TypedStruct to create structs. This is the code:

defmodule Shared.Data.Authorization do
  @moduledoc """
  Saves authorization details for a user. It also contains other details.
  """

  use TypedStruct

  alias Shared.Utils.Structs

  @type authorization :: %{
          (cookie :: String.t()) => String.t(),
          (token :: String.t()) => String.t()
        }

  @derive Jason.Encoder
  typedstruct enforce: true do
    @typedoc "Authorization information for a user"

    field(:cookie, String.t())
    field(:token, String.t())
  end

  @spec new(authorization()) :: __MODULE__.t()
  def new(%{"cookie" => cookie, "token" => token} = auth)
      when is_binary(cookie) and is_binary(token) do
    Structs.string_map_to_struct(auth, __MODULE__)
  end
end

The problem here is that Gradient does not seem to understand that t() is created, so it errors out:

 lib/data/authorization.ex: The function call on line 26 is expected to have type t() but it has type struct()
 24   def new(%{"cookie" => cookie, "token" => token} = auth)
 25       when is_binary(cookie) and is_binary(token) do
 26     Structs.string_map_to_struct(auth, __MODULE__)
 27   end

For additional context, here is the string_map_to_struct code:

  @spec string_map_to_struct(map, module | struct) :: struct
  def string_map_to_struct(data, target_struct) do
    data
    |> Morphix.atomorphiform!() # string_map to atom_map
    |> data_to_struct(target_struct)
  end

  @spec data_to_struct(Enumerable.t(), module | struct) :: struct
  def data_to_struct(data, target_struct), do: struct(target_struct, data)

Temporary fix

I decided to convert that code into its native form using defstruct:

defmodule Shared.Data.Authorization do
  @moduledoc """
  Saves authorization details for a user. It also contains other details.
  """

  alias Shared.Utils.Structs

  @enforce_keys [:cookie, :token]
  defstruct [:cookie, :token]

  @type authorization :: %{
          (cookie :: String.t()) => String.t(),
          (token :: String.t()) => String.t()
        }

  @typedoc "Authorization information for a user"
  @type t() :: %__MODULE__{
          cookie: String.t(),
          token: String.t()
        }

  @spec new(authorization()) :: t()
  def new(%{"cookie" => cookie, "token" => token} = auth)
      when is_binary(cookie) and is_binary(token) do
    Structs.string_map_to_struct(auth, __MODULE__)
  end
end

Gradient does not complain here.

Question

Is there a fix for this?
(other than removing typed struct?)

Most Liked

mafinar

mafinar

It’s cool that you also raised issue here: Gradient does not recognize type of TypedStruct structures · Issue #165 · esl/gradient · GitHub I am adding this as comment so that anyone coming to this post can go and follow the progress there. I myself am interested in this one. Thanks.

Fl4m3Ph03n1x

Fl4m3Ph03n1x

I usually update both threads if/when the issue is solved, so I got you covered there :stuck_out_tongue:

Where Next?

Popular Backend topics Top

Kurisu
Hello and happy new year! I would like to buy a Ruby On Rails ebook for learning purpose. What would be the ROR equivalent of “Programm...
New
ohm
Does anybody have good learning resources with regards to going into Event Driven Design, Architecture or Sourcing? I got recommended Er...
New
Jsdr3398
Are there any databases that require no setup (can be shipped in a small zip together with the project)?
New
TwistingTwists
Hello Folks, I am a novice developer from India. Intending to learn Elixir and web apps (phoenix framework). What are things that I MUS...
New
Ookma-Kyi
I am learning Elixir at the moment but am finding it difficult to learn. The issue is there aren’t any good tutorial sites out there when...
New
JimmyCarterSon
Hello, I am. very new to Elixir lang I have only been doing it for about 2 weeks. I recently started following this tutorial todo list, ...
New
Fl4m3Ph03n1x
Background I have recently been delving into more functional code. My objective right now is to get something similar to the IO Monad (in...
New
GermaVinsmoke
Does anyone know beginner friendly Elixir/Phoenix Open source projects? For learning purpose :slightly_smiling_face:
New
harwind
I received this error for a binary search programme in C, despite the fact that it requested for inputs and produced the right output. Th...
/c
New
Fl4m3Ph03n1x
Background I have an umbrella app where I use a dependecy called ETS. This dependency has a type called set_options that I use in some of...
New

Other popular topics Top

New
PragmaticBookshelf
Write Elixir tests that you can be proud of. Dive into Elixir’s test philosophy and gain mastery over the terminology and concepts that u...
New
DevotionGeo
I know that -t flag is used along with -i flag for getting an interactive shell. But I cannot digest what the man page for docker run com...
New
AstonJ
We have a thread about the keyboards we have, but what about nice keyboards we come across that we want? If you have seen any that look n...
New
AstonJ
I ended up cancelling my Moonlander order as I think it’s just going to be a bit too bulky for me. I think the Planck and the Preonic (o...
New
Exadra37
I am asking for any distro that only has the bare-bones to be able to get a shell in the server and then just install the packages as we ...
New
AstonJ
In case anyone else is wondering why Ruby 3 doesn’t show when you do asdf list-all ruby :man_facepalming: do this first: asdf plugin-upd...
New
PragmaticBookshelf
Use WebRTC to build web applications that stream media and data in real time directly from one user to another, all in the browser. ...
New
Maartz
Hi folks, I don’t know if I saw this here but, here’s a new programming language, called Roc Reminds me a bit of Elm and thus Haskell. ...
New
PragmaticBookshelf
Programming Ruby is the most complete book on Ruby, covering both the language itself and the standard library as well as commonly used t...
New