E-xyza/Exonerate

Simple schema triggers protocol Enumerable not implemented for "string" of type BitString

Closed this issue · 2 comments

The following simple JSON Schema fails to compile, (in fact not a single schema I tried worked) but this reproduces the issue succinctly:

$ mix new json_test
* creating README.md
* creating .formatter.exs
* creating .gitignore
* creating mix.exs
* creating lib
* creating lib/json_test.ex
* creating test
* creating test/test_helper.exs
* creating test/json_test_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

    cd json_test
    mix test

Run "mix help" for more commands.
$ cd json_test 

mix.exs:

defmodule JsonTest.MixProject do
  use Mix.Project

  def project do
    [
      app: :json_test,
      version: "0.1.0",
      elixir: "~> 1.15",
      start_permanent: Mix.env() == :prod,
      deps: deps()
    ]
  end

  # Run "mix help compile.app" to learn about applications.
  def application do
    [
      extra_applications: [:logger]
    ]
  end

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
      {:exonerate, "~> 1.1.2"}
    ]
  end
end
$ mix deps.get
Resolving Hex dependencies...
Resolution completed in 0.093s
New:
  exonerate 1.1.2
  jason 1.4.1
  json_ptr 1.2.0
  match_spec 0.3.1
* Getting exonerate (Hex package)
* Getting jason (Hex package)
* Getting json_ptr (Hex package)
* Getting match_spec (Hex package)
You have added/upgraded packages you could sponsor, run `mix hex.sponsor` to learn more

lib/json_test.ex:

defmodule JsonTest do
  require Exonerate

  Exonerate.function_from_string(:def, :validate_api, ~S"""
  {
      "$schema": "http://json-schema.org/draft-04/schema#",
      "title": "JSON validation failure",
      "type": "object",
      "id": "https://example.com/fail.json",
      "definitions": {
          "versionType": {
              "type": "string",
              "enum": [ "1.0", "1.1", "2.0" ]
          }
      },
      "properties": {
          "version": { "$ref": "#/definitions/versionType" }
      },
      "required": [ "version" ]
  }
  """)
end
$ iex -S mix
Compiling 1 file (.ex)

== Compilation error in file lib/json_test.ex ==
** (Protocol.UndefinedError) protocol Enumerable not implemented for "string" of type BitString
    (elixir 1.15.4) lib/enum.ex:1: Enumerable.impl_for!/1
    (elixir 1.15.4) lib/enum.ex:166: Enumerable.reduce/3
    (elixir 1.15.4) lib/enum.ex:4387: Enum.sort/2
    (exonerate 1.1.2) lib/exonerate/degeneracy.ex:278: Exonerate.Degeneracy.class/1
    (exonerate 1.1.2) lib/exonerate/combining/ref.ex:44: Exonerate.Combining.Ref.build_filter/6
    (exonerate 1.1.2) expanding macro: Exonerate.Combining.Ref.filter/3
    lib/json_test.ex:4: JsonTest (module)
    (exonerate 1.1.2) expanding macro: Exonerate.Context.filter/3

If I either remove the id OR if I refactor the schema as follows it does not error:

defmodule JsonTest do
  require Exonerate

  Exonerate.function_from_string(:def, :validate_api, ~S"""
  {
      "$schema": "http://json-schema.org/draft-04/schema#",
      "title": "JSON validation failure",
      "type": "object",
      "id": "https://example.com/fail.json",
      "definitions": {
      },
      "properties": {
          "version": {
              "type": "string",
              "enum": [ "1.0", "1.1", "2.0" ]
          }
      },
      "required": [ "version" ]
  }
  """)
end
$ iex -S mix           
Compiling 1 file (.ex)
Erlang/OTP 26 [erts-14.0.2] [source] [64-bit] [smp:32:24] [ds:32:24:10] [async-threads:1] [jit:ns]

Interactive Elixir (1.15.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> %{"version" => "1.1"} |> JsonTest.validate_api()
:ok

thanks! Will take a look, I have an idea of what's wrong.

Fixed and available as 1.1.3