Coverage for src / lexigram / contracts / core / validation.py: 0%
15 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-15 18:57 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-15 18:57 +0800
1"""Validation types and exceptions.
3This module re-exports ``ValidationError`` from ``lexigram.contracts.exceptions.domain``
4for convenience, and defines validation protocols and result type aliases.
5"""
7from __future__ import annotations
9from typing import Any, Protocol, TypeAlias, TypeVar
11from lexigram.contracts.core.result import Result
13# ValidationError is defined in exceptions.domain - re-exported here for convenience
14from lexigram.contracts.exceptions.domain import FieldError, ValidationError
16T_co = TypeVar("T_co", covariant=True)
18RuleResult: TypeAlias = Result[Any, FieldError]
19ValidationResult: TypeAlias = Result[dict[str, Any], ValidationError]
22class RuleProtocol(Protocol[T_co]): # type: ignore[misc]
23 """Protocol for a single validation rule applied to one field."""
25 def __call__(self, value: Any, field_name: str) -> Result[T_co, FieldError]:
26 """Validate *value* for *field_name* and return a Result."""
27 ...
30class AsyncRuleProtocol(Protocol[T_co]): # type: ignore[misc]
31 """Protocol for a single async validation rule applied to one field."""
33 async def __call__(self, value: Any, field_name: str) -> Result[T_co, FieldError]:
34 """Asynchronously validate *value* for *field_name* and return a Result."""
35 ...
38class ValidatorProtocol(Protocol[T_co]):
39 """Protocol for a full-document validator that returns a Result."""
41 def validate(self, data: dict[str, Any]) -> ValidationResult:
42 """Validate *data* and return a Result with the cleaned dict or error."""
43 ...
45 def validate_object(self, obj: Any) -> Result[Any, ValidationError]:
46 """Validate *obj* by reading its attributes."""
47 ...
50__all__ = [
51 "AsyncRuleProtocol",
52 "FieldError",
53 "RuleProtocol",
54 "RuleResult",
55 "ValidationError",
56 "ValidationResult",
57 "ValidatorProtocol",
58]