Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Type Fails at get_spec_type #4

Closed
ckreiling opened this issue Feb 26, 2020 · 3 comments · Fixed by #5
Closed

Custom Type Fails at get_spec_type #4

ckreiling opened this issue Feb 26, 2020 · 3 comments · Fixed by #5
Assignees
Labels

Comments

@ckreiling
Copy link

ckreiling commented Feb 26, 2020

Hi, I want to say I'm excited to be using your library to quickly generate a config module for a Spotify client I'm writing at the moment. It vastly simplifies some of my logic and makes it easy for the user (and me!) to fetch (and potentially update!) their configuration for my library at runtime.

However, I'm using Elixir 1.10.0 and Erlang 22, and have ran into the following issue with defining my own custom type.

The type is for validating that a user has passed only Spotify scopes (to avoid any oopsies) as either a list or space-separated string of scopes. It's rather simple:

defmodule DeSpotify.ScopeList do
  use Skogsra.Type

  @spotify_scopes ~w[
      ugc-image-upload
      user-modify-playback-state
      # ... reduced for brevity 
    ]

  def cast(str) when is_binary(str) do
    str
    |> String.split(" ")
    |> cast()
  end

  def cast(list) when is_list(list) do
    if Enum.all?(list, &(&1 in @spotify_scopes)), do: {:ok, list}, else: :error
  end

  def cast(_), do: :error
end

And then used it in a module which has use Skogsra at the top, like so:

  @envdoc "Spotify Authorization scopes"
  app_env(:scopes, :despotify, :scopes,
    skip_system: true,
    type: DeSpotify.ScopeList,
    default: ~w[user-read-email]
  )

Unfortunately it seems that at compile time, the private Skogsra.Spec.get_spec_type/1 function is receiving {:__aliases__, _, [:DeSpotify, :ScopeList]}, but does not have a function definition for matching on an AST. Here is the compilation error in full:

== Compilation error in file lib/config.ex ==
** (FunctionClauseError) no function clause matching in Skogsra.Spec.get_spec_type/1

    The following arguments were given to Skogsra.Spec.get_spec_type/1:

        # 1
        {:__aliases__, [line: 53], [:ScopeList]}

    Attempted function clauses (showing 9 out of 9):

        defp get_spec_type(:binary)
        defp get_spec_type(:integer)
        defp get_spec_type(:float)
        defp get_spec_type(:boolean)
        defp get_spec_type(:atom)
        defp get_spec_type(:module)
        defp get_spec_type(:unsafe_module)
        defp get_spec_type(module) when is_atom(module)
        defp get_spec_type(options) when is_list(options)

    lib/skogsra/spec.ex:60: Skogsra.Spec.get_spec_type/1
    lib/skogsra/spec.ex:11: Skogsra.Spec.gen_full_spec/2
    expanding macro: Skogsra.app_env/4
    lib/config.ex:51: DeSpotify.Config (module)

Is there something that I am missing or getting wrong? My knee-jerk intuition is that a subtle change in how Elixir produces :__aliases__ ASTs has happened across major versions (note again that I'm using Elixir 1.10.0), but I have not looked deeper. Let me know if I can provide any more information and I am looking forward to hearing from you.

Christian

@alexdesousa alexdesousa self-assigned this Feb 26, 2020
@alexdesousa
Copy link
Member

Hi @ckreiling Thanks for the support! I will take a look at it. This is definitely a bug because your code looks fine :)

@alexdesousa
Copy link
Member

alexdesousa commented Feb 26, 2020

@ckreiling thanks again for reporting this bug. It should already be fixed in version 2.1.1 :)

@ckreiling
Copy link
Author

Thanks for the snappy fix! The new tests for custom types look great too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants