Packages

ISO/HL7 FHIR Application Server

Current section

Files

Jump to
hl7 lib validation schema_validator.ex
Raw

lib/validation/schema_validator.ex

defmodule Xema.SchemaValidator do
@moduledoc """
A validator for the schema input.
"""
alias Xema.{Ref, Schema, SchemaError}
def schema,
do:
struct(Xema,
refs: %{
"#/definitions/keywords" => %Schema{
properties: %{
examples: %Schema{items: %Schema{type: true}, type: :list },
format: %Schema{type: :atom},
if: %Schema{ref: %Ref{pointer: "#/definitions/schema"}},
exclusive_minimum: %Schema{type: [:boolean, :number]},
max_length: %Schema{ref: %Ref{pointer: "#/definitions/non_negative_integer"}},
max_items: %Schema{ref: %Ref{pointer: "#/definitions/non_negative_integer"}},
any_of: %Schema{ref: %Ref{pointer: "#/definitions/schemas"}},
pattern_properties: %Schema{
additional_properties: %Schema{ref: %Ref{pointer: "#/definitions/schema"}},
property_names: %Schema{any_of: [%Schema{format: :regex, type: :string},%Schema{module: Regex, type: :struct}]},
type: :map
},
const: %Schema{type: true},
description: %Schema{type: :string},
one_of: %Schema{ref: %Ref{pointer: "#/definitions/schemas"}},
properties: %Schema{
additional_properties: %Schema{ref: %Ref{pointer: "#/definitions/schema"}},
type: :map
},
id: %Schema{format: :uri_reference, type: :string},
pattern: %Schema{
any_of: [%Schema{format: :regex, type: :string}, %Schema{module: Regex, type: :struct}]
},
else: %Schema{ref: %Ref{pointer: "#/definitions/schema"}},
items: %Schema{
any_of: [
%Schema{ref: %Ref{pointer: "#/definitions/schema"}},
%Schema{ref: %Ref{pointer: "#/definitions/schemas"}}
]
},
comment: %Schema{type: :string},
exclusive_maximum: %Schema{type: [:boolean, :number]},
default: %Schema{type: true},
minimum: %Schema{type: :number},
ref: %Schema{format: :uri_reference, type: :string},
maximum: %Schema{type: :number},
min_items: %Schema{
ref: %Ref{pointer: "#/definitions/non_negative_integer"}
},
min_length: %Schema{
ref: %Ref{pointer: "#/definitions/non_negative_integer"}
},
title: %Schema{type: :string},
enum: %Schema{
items: %Schema{type: true},
min_items: 1,
type: :list,
unique_items: true
},
unique_items: %Schema{type: :boolean},
then: %Schema{ref: %Ref{pointer: "#/definitions/schema"}},
contains: %Schema{ref: %Ref{pointer: "#/definitions/schema"}},
min_properties: %Schema{ref: %Ref{pointer: "#/definitions/non_negative_integer"}},
multiple_of: %Schema{exclusive_minimum: 0, type: :number},
property_names: %Schema{ref: %Ref{pointer: "#/definitions/schema"}},
required: %Schema{
any_of: [
%Schema{items: %Schema{type: :string}, type: :list},
%Schema{items: %Schema{type: :atom}, type: :list}
]
},
dependencies: %Schema{
additional_properties: %Schema{
any_of: [
%Schema{type: :string},
%Schema{type: :atom},
%Schema{items: %Schema{type: :string},type: :list},
%Schema{items: %Schema{type: :atom}, type: :list},
%Schema{ref: %Ref{pointer: "#/definitions/schema"}}
]
},
type: :map
},
schema: %Schema{format: :uri, type: :string},
max_properties: %Schema{
ref: %Ref{pointer: "#/definitions/non_negative_integer"}
},
not: %Schema{ref: %Ref{pointer: "#/definitions/schema"}},
additional_properties: %Schema{
ref: %Ref{pointer: "#/definitions/schema"}
},
additional_items: %Schema{
ref: %Ref{pointer: "#/definitions/schema"}
},
definitions: %Schema{
additional_properties: %Schema{
ref: %Ref{pointer: "#/definitions/schema"}
},
type: :map
},
all_of: %Schema{
ref: %Ref{pointer: "#/definitions/schemas"}
}
},
type: :keyword
},
"#/definitions/keywords/properties/ref" => %Schema{
format: :uri_reference,
type: :string
},
"#/definitions/non_negative_integer" => %Schema{
minimum: 0,
type: :integer
},
"#/definitions/ref" => %Schema{
items: [
%Schema{const: :ref, type: :atom},
%Schema{
ref: %Ref{pointer: "#/definitions/keywords/properties/ref"}
}
],
max_length: 2,
min_length: 2,
type: :tuple
},
"#/definitions/schema" => %Schema{
any_of: [
%Schema{ref: %Ref{pointer: "#"}},
%Schema{ref: %Ref{pointer: "#/definitions/type"}},
%Schema{ref: %Ref{pointer: "#/definitions/types"}},
%Schema{ref: %Ref{pointer: "#/definitions/ref"}},
%Schema{ref: %Ref{pointer: "#/definitions/keywords"}},
%Schema{module: Xema, type: :struct},
%Schema{type: :atom}
]
},
"#/definitions/schemas" => %Schema{
items: %Schema{ref: %Ref{pointer: "#/definitions/schema"}},
type: :list
},
"#/definitions/type" => %Schema{
enum: [
:any,
:atom,
:boolean,
false,
:float,
:integer,
:keyword,
:list,
:map,
nil,
:number,
:string,
:struct,
true,
:tuple
],
type: :atom
},
"#/definitions/types" => %Schema{
items: %Schema{ref: %Ref{pointer: "#/definitions/type"}},
type: :list
}
},
schema: %Schema{
definitions: %{
keywords: %Schema{
properties: %{
examples: %Schema{
items: %Schema{type: true},
type: :list
},
format: %Schema{
enum: [
:date,
:date_time,
:email,
:hostname,
:ipv4,
:ipv6,
:json_pointer,
:regex,
:relative_json_pointer,
:time,
:uri,
:uri_fragment,
:uri_path,
:uri_query,
:uri_reference,
:uri_template,
:uri_userinfo
],
type: :atom
},
if: %Schema{
ref: %Ref{pointer: "#/definitions/schema"}
},
exclusive_minimum: %Schema{type: [:boolean, :number]},
max_length: %Schema{
ref: %Ref{pointer: "#/definitions/non_negative_integer"}
},
max_items: %Schema{
ref: %Ref{pointer: "#/definitions/non_negative_integer"}
},
any_of: %Schema{
ref: %Ref{pointer: "#/definitions/schemas"}
},
pattern_properties: %Schema{
additional_properties: %Schema{
ref: %Ref{pointer: "#/definitions/schema"}
},
property_names: %Schema{
any_of: [
%Schema{format: :regex, type: :string},
%Schema{module: Regex, type: :struct}
]
},
type: :map
},
const: %Schema{type: true},
description: %Schema{type: :string},
one_of: %Schema{
ref: %Ref{pointer: "#/definitions/schemas"}
},
properties: %Schema{
additional_properties: %Schema{
ref: %Ref{pointer: "#/definitions/schema"}
},
type: :map
},
id: %Schema{format: :uri_reference, type: :string},
pattern: %Schema{
any_of: [
%Schema{format: :regex, type: :string},
%Schema{module: Regex, type: :struct}
]
},
else: %Schema{
ref: %Ref{pointer: "#/definitions/schema"}
},
items: %Schema{
any_of: [
%Schema{
ref: %Ref{pointer: "#/definitions/schema"}
},
%Schema{
ref: %Ref{pointer: "#/definitions/schemas"}
}
]
},
comment: %Schema{type: :string},
exclusive_maximum: %Schema{type: [:boolean, :number]},
default: %Schema{type: true},
minimum: %Schema{type: :number},
ref: %Schema{format: :uri_reference, type: :string},
maximum: %Schema{type: :number},
min_items: %Schema{
ref: %Ref{pointer: "#/definitions/non_negative_integer"}
},
min_length: %Schema{
ref: %Ref{pointer: "#/definitions/non_negative_integer"}
},
title: %Schema{type: :string},
enum: %Schema{
items: %Schema{type: true},
min_items: 1,
type: :list,
unique_items: true
},
unique_items: %Schema{type: :boolean},
then: %Schema{
ref: %Ref{pointer: "#/definitions/schema"}
},
contains: %Schema{
ref: %Ref{pointer: "#/definitions/schema"}
},
min_properties: %Schema{
ref: %Ref{pointer: "#/definitions/non_negative_integer"}
},
multiple_of: %Schema{exclusive_minimum: 0, type: :number},
property_names: %Schema{
ref: %Ref{pointer: "#/definitions/schema"}
},
required: %Schema{
any_of: [
%Schema{
items: %Schema{type: :string},
type: :list
},
%Schema{items: %Schema{type: :atom}, type: :list}
]
},
dependencies: %Schema{
additional_properties: %Schema{
any_of: [
%Schema{type: :string},
%Schema{type: :atom},
%Schema{
items: %Schema{type: :string},
type: :list
},
%Schema{
items: %Schema{type: :atom},
type: :list
},
%Schema{
ref: %Ref{pointer: "#/definitions/schema"}
}
]
},
type: :map
},
schema: %Schema{format: :uri, type: :string},
max_properties: %Schema{
ref: %Ref{pointer: "#/definitions/non_negative_integer"}
},
not: %Schema{
ref: %Ref{pointer: "#/definitions/schema"}
},
additional_properties: %Schema{
ref: %Ref{pointer: "#/definitions/schema"}
},
additional_items: %Schema{
ref: %Ref{pointer: "#/definitions/schema"}
},
definitions: %Schema{
additional_properties: %Schema{
ref: %Ref{pointer: "#/definitions/schema"}
},
type: :map
},
all_of: %Schema{
ref: %Ref{pointer: "#/definitions/schemas"}
}
},
type: :keyword
},
non_negative_integer: %Schema{minimum: 0, type: :integer},
ref: %Schema{
items: [
%Schema{const: :ref, type: :atom},
%Schema{
ref: %Ref{
pointer: "#/definitions/keywords/properties/ref"
}
}
],
max_length: 2,
min_length: 2,
type: :tuple
},
schema: %Schema{
any_of: [
%Schema{ref: %Ref{pointer: "#"}},
%Schema{ref: %Ref{pointer: "#/definitions/type"}},
%Schema{ref: %Ref{pointer: "#/definitions/types"}},
%Schema{ref: %Ref{pointer: "#/definitions/ref"}},
%Schema{ref: %Ref{pointer: "#/definitions/keywords"}},
%Schema{module: Xema, type: :struct}
]
},
schemas: %Schema{
items: %Schema{
ref: %Ref{pointer: "#/definitions/schema"}
},
type: :list
},
type: %Schema{
enum: [
:any,
:atom,
:boolean,
false,
:float,
:integer,
:keyword,
:list,
:map,
nil,
:number,
:string,
:struct,
true,
:tuple
],
type: :atom
},
types: %Schema{
items: %Schema{ref: %Ref{pointer: "#/definitions/type"}},
type: :list
}
},
items: [
%Schema{
any_of: [
%Schema{ref: %Ref{pointer: "#/definitions/type"}},
%Schema{ref: %Ref{pointer: "#/definitions/types"}}
]
},
%Schema{ref: %Ref{pointer: "#/definitions/keywords"}}
],
max_items: 2,
min_items: 2,
type: :tuple
}
)
@doc """
Returns `:ok` if the data valid against the xema schema.
"""
@spec validate!(any) :: :ok
def validate!(data) do
case Xema.validate(schema(), data, []) do
:ok ->
:ok
{:error, reason} ->
raise SchemaError, reason
end
end
end