Sinter.Validator (Sinter v0.0.1)

View Source

The unified validation engine for Sinter.

This module provides the single validation pipeline that handles all types of validation in Sinter. It processes schemas created by Sinter.Schema.define/2 and runs a clean, predictable validation process.

Validation Pipeline

  1. Input Validation - Ensure input is valid format
  2. Required Field Check - Verify all required fields are present
  3. Field Validation - Validate each field against its type and constraints
  4. Strict Mode Check - Reject unknown fields if strict mode enabled
  5. Post Validation - Run custom cross-field validation if configured

Design Philosophy

The validator focuses purely on validation - it does NOT perform data transformation. Any data transformation should be explicit in your application code, keeping your validation logic pure and your transformations visible.

Usage

schema = Sinter.Schema.define([
  {:name, :string, [required: true, min_length: 2]},
  {:age, :integer, [optional: true, gt: 0]}
])

# Basic validation
{:ok, validated} = Sinter.Validator.validate(schema, %{name: "Alice", age: 30})

# With coercion
{:ok, validated} = Sinter.Validator.validate(schema, %{name: "Alice", age: "30"}, coerce: true)

# Batch validation
data_list = [%{name: "Alice", age: 30}, %{name: "Bob", age: 25}]
{:ok, validated_list} = Sinter.Validator.validate_many(schema, data_list)

Summary

Functions

Validates data against a Sinter schema.

Validates data against a schema, raising an exception on failure.

Validates multiple data items against the same schema efficiently.

Validates a stream of data maps against a schema with memory efficiency.

Types

validation_opts()

@type validation_opts() :: [
  coerce: boolean(),
  strict: boolean(),
  path: [atom() | String.t() | integer()]
]

validation_result()

@type validation_result() :: {:ok, map()} | {:error, [Sinter.Error.t()]}

Functions

validate(schema, data, opts \\ [])

@spec validate(Sinter.Schema.t(), map(), validation_opts()) :: validation_result()

Validates data against a Sinter schema.

This is the core validation function that all other validation in Sinter ultimately uses. It implements a clean, predictable pipeline.

Parameters

  • schema - A schema created by Sinter.Schema.define/2
  • data - The data to validate (must be a map)
  • opts - Validation options

Options

  • :coerce - Enable type coercion (default: false)
  • :strict - Override schema's strict setting
  • :path - Base path for error reporting (default: [])

Returns

  • {:ok, validated_data} - Validation succeeded
  • {:error, errors} - List of validation errors

Examples

iex> schema = Sinter.Schema.define([
...>   {:name, :string, [required: true]},
...>   {:age, :integer, [optional: true, gt: 0]}
...> ])
iex> Sinter.Validator.validate(schema, %{name: "Alice", age: 30})
{:ok, %{name: "Alice", age: 30}}

iex> Sinter.Validator.validate(schema, %{age: 30})
{:error, [%Sinter.Error{path: [:name], code: :required, ...}]}

validate!(schema, data, opts \\ [])

@spec validate!(Sinter.Schema.t(), map(), validation_opts()) :: map() | no_return()

Validates data against a schema, raising an exception on failure.

Examples

iex> validated = Sinter.Validator.validate!(schema, data)
%{name: "Alice", age: 30}

# Raises Sinter.ValidationError on failure

validate_many(schema, data_list, opts \\ [])

@spec validate_many(Sinter.Schema.t(), [map()], validation_opts()) ::
  {:ok, [map()]} | {:error, %{required(integer()) => [Sinter.Error.t()]}}

Validates multiple data items against the same schema efficiently.

Parameters

  • schema - Schema to validate against
  • data_list - List of data maps to validate
  • opts - Validation options

Returns

  • {:ok, validated_list} if all validations succeed
  • {:error, errors_by_index} if any validation fails

Examples

iex> data_list = [
...>   %{name: "Alice", age: 30},
...>   %{name: "Bob", age: 25}
...> ]
iex> Sinter.Validator.validate_many(schema, data_list)
{:ok, [%{name: "Alice", age: 30}, %{name: "Bob", age: 25}]}

validate_stream(schema, data_stream, opts \\ [])

@spec validate_stream(Sinter.Schema.t(), Enumerable.t(), validation_opts()) ::
  Enumerable.t()

Validates a stream of data maps against a schema with memory efficiency.

This function is designed for processing large datasets without loading everything into memory at once. Perfect for DSPEx teleprompter optimization on large training sets.

Parameters

  • schema - A schema created by Sinter.Schema.define/2
  • data_stream - An Enumerable of data maps to validate
  • opts - Validation options

Returns

  • A stream of {:ok, validated_data} or {:error, [Error.t()]} tuples

Examples

iex> schema = Sinter.Schema.define([{:id, :integer, [required: true]}])
iex> data_stream = Stream.map(1..1000, &%{"id" => &1})
iex> results = Sinter.Validator.validate_stream(schema, data_stream)
iex> Enum.take(results, 3)
[
  {:ok, %{id: 1}},
  {:ok, %{id: 2}},
  {:ok, %{id: 3}}
]

Memory Efficiency

This function processes items one at a time and does not accumulate results, making it suitable for very large datasets that would not fit in memory.