Skip to content

nicolkill/map_schema_validator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

map_schema_validator

It's a map format verifier, verify if keys/values exist in a given map, short and quick, you can specify more than one format and verify list of values.

The motivation of create this library was verify that a json file content has a specific format and fail in case that not matches raises an error with the route to the invalid field

Docs here!

Installation

If available in Hex, the package can be installed by adding map_schema_validator to your list of dependencies in mix.exs:

def deps do
  [
    {:map_schema_validator, "~> 0.1.8"}
  ]
end

How to use it?

Just use the function MapSchemaValidator.validate/2 or MapSchemaValidator.validate!/2

Also, you can use the module MapSchemaValidator.Schema to create a schema with all the properties and directly validate the maps without have the schema in other place

Basic usage

A basic example of the way to use

# MapSchemaValidator
schema = %{
  field: %{
    inner_field: :string
  }
}

map = %{
  field: %{
    inner_field: "value"
  }
}

case MapSchemaValidator.validate(schema, map) do
  {:ok, _} ->
    :ok
    # your stuff
  {:error, %MapSchemaValidator.InvalidMapError{message: message}} ->
    :error
    # failure
end

try do
  :ok = MapSchemaValidator.validate!(schema, map)
rescue
  e in MapSchemaValidator.InvalidMapError -> 
    e.message
end

# MapSchemaValidator.Schema

defmodule InnerSchemaModule do
  use MapSchemaValidator.Schema

  field :inner_field, :string
end

defmodule SchemaModule do
  use MapSchemaValidator.Schema

  field :field, InnerSchemaModule
end

{:ok, _} = SchemaModule.validate(map)

Possible values

You can check inner list of maps or even list of possible values, or even optional values using ? at the end of the field name in the schema

:float, :integer, :number, :boolean, :string, :datetime, :date, :time, :uuid, [:list], %{type: :map}, [%{type: :map}]

the list of maps [%{type: :map}] are just valid with one object schema, in this case you are validating that an list has the format of the map, but only it's supported one element, multiple object schema options are in backlog

Primitive types

schema = %{
  value_number: :number,
  value_float: :float,
  value_integer: :integer,
  value_boolean: :boolean,
  value_string: :string,
  value_datetime: :datetime,
  value_date: :date,
  value_time: :time,
  value_uuid: :uuid
}
map = %{
  value_number: 1,
  value_float: 1.1,
  value_integer: 1,
  value_boolean: false,
  value_string: "value string",
  value_datetime: "2015-01-23 23:50:07",
  value_date: "2015-01-23",
  value_time: "23:50:07",
  value_uuid: "fcfe5f21-8a08-4c9a-9f97-29d2fd6a27b9"
}

{:ok, _} = MapSchemaValidator.validate(schema, map)

Optional keys

schema = %{
  mandatory_value: :string,
  optional_value?: :number
}
map = %{
  mandatory_value: "value string"
}

{:ok, _} = MapSchemaValidator.validate(schema, map)

Just adding the ? char at the end of the key (like Typescript)

Nested Maps

schema = %{
  value_map: %{
    inner_map: %{
      inner_value: :string
    }
  }
}
map = %{
  value_map: %{
    inner_map: %{
      inner_value: "value string"
    }
  }
}

{:ok, _} = MapSchemaValidator.validate(schema, map)

List of allowed values

schema = %{
  value_one_of: [:string, :number],
}
map = %{
  value_one_of: "value string",
}

{:ok, _} = MapSchemaValidator.validate(schema, map)

map = %{
  value_one_of: 100,
}

{:ok, _} = MapSchemaValidator.validate(schema, map)

List of allowed values and list of values

schema = %{
  value_list: [:string, :number],
}
map = %{
  value_list: ["value string", 1],
}

{:ok, _} = MapSchemaValidator.validate(schema, map)

List of maps with format

schema = %{
  list: [
    %{
      inner_value: :string,
      inner_map: %{
        inner_value: :string
      },
      inner_list: [
        %{
          inner_value_level_2: :number
        }
      ]
    }  
  ]
}
map = %{
  list: [
    %{
      inner_value: "value string",
      inner_map: %{
        inner_value: "value string"
      },
      inner_list: [
        %{
          inner_value_level_2: 100
        }
      ]
    }  
  ]
}

{:ok, _} = MapSchemaValidator.validate(schema, map)

In this case are allowed just one schema per list, multiple are work in progress

Advanced example

schema = %{
  list: [
    %{
      inner_field: [:string, :number],
      inner_list: [
        %{
          inner_leven_2_flag: [:boolean, :integer]
        }
      ],
      inner_optional_flag?: :boolean
    }
  ]
}
map = %{
  list: [
    %{
      inner_field: "value string",
      inner_list: [
        %{
          inner_leven_2_flag: true
        }
      ],
      inner_optional_flag: false
    },
    %{
      inner_field: 10,
      inner_list: [
        %{
          inner_leven_2_flag: true
        }
      ]
    }
  ]
}

{:ok, _} = MapSchemaValidator.validate(schema, map)

defmodule InnerListElementModule do
  use MapSchemaValidator.Schema

  field :inner_leven_2_flag, [:boolean, :integer]
end

defmodule ListElementModule do
  use MapSchemaValidator.Schema

  field :inner_field, [:string, :number]
  field :inner_list, [InnerListElementModule]
  field :inner_optional_flag?, :boolean
end

defmodule SchemaModule do
  use MapSchemaValidator.Schema

  field :list, [ListElementModule]
end

{:ok, _} = SchemaModule.validate(map)

Releases

No releases published

Packages

No packages published