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

UndefinedFunctionError when using map(:string) field type #57

Open
LeartS opened this issue Jul 25, 2024 · 2 comments
Open

UndefinedFunctionError when using map(:string) field type #57

LeartS opened this issue Jul 25, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@LeartS
Copy link

LeartS commented Jul 25, 2024

Contract taken from the README (and slimmed down):

defmodule UserContract do
  use Drops.Contract

  schema do
    %{
      required(:name) => string(),
      optional(:settings) => map(:string),
      required(:address) => maybe(:string)
    }
  end
end

Trying to conform a map with settings results in an unmanaged UndefinedFunctionError exception:

UserContract.conform(%{name: "Jane", settings: %{"theme" => "dark"}, address: "main road 1"})
** (UndefinedFunctionError) function Drops.Predicates.string/1 is undefined or private
    (drops 0.2.0) Drops.Predicates.string(%{"theme" => "dark"})
    (drops 0.2.0) lib/drops/predicates/helpers.ex:22: Drops.Predicates.Helpers.apply_predicate/2
    (elixir 1.17.1) lib/enum.ex:2531: Enum."-reduce/3-lists^foldl/2-0-"/3
    (drops 0.2.0) lib/drops/types/map/key.ex:15: Drops.Types.Map.Key.validate/2
    (elixir 1.17.1) lib/enum.ex:1703: Enum."-map/2-lists^map/1-1-"/2
    (drops 0.2.0) lib/drops/types/map.ex:63: Drops.Types.Map.Validator.validate/2
    #cell:rziepynrh7l5vn3j:2: UserContract.conform/3
    #cell:7x24e72nc24vkawk:1: (file)

No issue if we remove the settings key from the map:

UserContract.conform(%{name: "Jane", address: "main road 1"})
# {:ok, %{name: "Jane", address: "main road 1"}}

Is it a bug with the library, or an incorrect/outdated README/documentation?
If the latter, what's the proper way to have a field that needs to be a map with string values?

@solnic
Copy link
Owner

solnic commented Jul 26, 2024

Thanks for reporting this - it is not yet supported, but will be eventually. We could have a syntax like that for this:

map(keys: any(), values: string())

# or

map(%{ any() => string() })

WDYT?

@solnic solnic added the enhancement New feature or request label Jul 26, 2024
@LeartS
Copy link
Author

LeartS commented Jul 28, 2024

Personally, I like the first syntax. map(%{any() => string()}) makes me think of a map of maps; and also the keyword list syntax is more readable and would allow for more options and defaults.

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

No branches or pull requests

2 participants