defmodule JValid do @moduledoc """ Macro allows to include JSON Schema into your code and validate maps based on them. """ @doc false defmacro __using__(_opts) do quote do import JValid @schemas [] end end @doc """ Load schema at compile time to be later used in validator. This macro will include in inline in a module scope. It can save resources and reduce application size. Example: defmodule Sample use_schema :schema, "test/support/schema.json" end """ defmacro use_schema(name, file) when is_atom(name) and is_binary(file) do quote bind_quoted: binding() do alias NExJsonSchema.Schema source = file |> File.read!() |> Jason.decode!() |> Schema.resolve() @schemas [{name, source} | @schemas] end end @doc """ Load schema at compile time to be later used in validator. This macro will include in inline in a function scope. Example: schema = load_schema "test/support/schema.json" """ defmacro load_schema(file) when is_binary(file) do quote bind_quoted: binding() do alias NExJsonSchema.Schema file |> File.read!() |> Jason.decode!() |> Schema.resolve() end end @doc """ Validate map using previously loaded schema. Returns true if schema is valid. Example: use JValid # Include schema in a module scope use_schema :schema, "test/support/schema.json" # ... valid_schema?(:schema, map) # Include schema in a function scope "test/support/schema.json" |> load_schema |> valid_schema?(map) """ defmacro valid_schema?(schema, map) when is_atom(schema) do quote bind_quoted: binding() do alias NExJsonSchema.Validator @schemas |> Keyword.get(schema) |> Validator.valid?(map) end end defmacro valid_schema?(schema, map) do quote bind_quoted: binding() do alias NExJsonSchema.Validator schema |> Validator.valid?(map) end end @doc """ Validate map using previously loaded schema. Returns `:ok` if map is valid, otherwise - `{:error, reason}`. Example: use JValid # Include schema in a module scope use_schema :schema, "test/support/schema.json" # ... validate_schema?(:schema, map) # Include schema in a function scope "test/support/schema.json" |> load_schema |> validate_schema?(map) """ defmacro validate_schema(schema, map) when is_atom(schema) do quote bind_quoted: binding() do alias NExJsonSchema.Validator @schemas |> Keyword.get(schema) |> Validator.validate(map) end end defmacro validate_schema(schema, map) do quote bind_quoted: binding() do alias NExJsonSchema.Validator schema |> Validator.validate(map) end end end