Skip to main content

wellformed/
lib.rs

1//! wellformed
2//!
3//! A portable FormSpec IR with Zod-like authoring for defining form schemas,
4//! transforms, constraints, and error metadata.
5//!
6//! ## Overview
7//!
8//! wellformed provides a declarative, portable way to define form validation schemas
9//! that can be:
10//! - Serialized to JSON for cross-language interop
11//! - Executed in the Rust runtime
12//! - Used to generate code for other languages (TypeScript, OpenAPI, etc.)
13//!
14//! ## Key Features
15//!
16//! - **Type Layer**: Define structure with primitives, objects, arrays, enums
17//! - **Transform Layer**: Normalize data before validation (trim, digits_only, etc.)
18//! - **Constraint Layer**: Portable predicate AST for validation rules
19//! - **Error Layer**: Structured, stable error codes with help text
20//!
21//! ## Optional Features
22//!
23//! - **`address`**: Enables address parsing predicates through the `postal`
24//!   crate. This feature requires the native libpostal C library, headers, and
25//!   parser data to be installed on the target system.
26//!
27//! ## Example
28//!
29//! ```rust
30//! use wellformed::ir::*;
31//! use wellformed::runtime::validate;
32//! use serde_json::json;
33//!
34//! // Define a schema
35//! let schema = Schema::new(
36//!     "1.0.0",
37//!     TypeSchema::Object(
38//!         ObjectSchema::new()
39//!             .property(
40//!                 "tin",
41//!                 TypeSchema::String(
42//!                     StringSchema::new()
43//!                         .transform(Transform::digits_only())
44//!                         .constraint(Constraint::new(
45//!                             Predicate::regex(r"^\d{9}$"),
46//!                             ErrorMeta::new("TIN_INVALID", "TIN must be 9 digits"),
47//!                         )),
48//!                 ),
49//!             )
50//!             .property("name", TypeSchema::string()),
51//!     ),
52//! );
53//!
54//! // Validate a value
55//! let mut value = json!({
56//!     "tin": "123-45-6789",
57//!     "name": "Alice"
58//! });
59//!
60//! let result = validate(&schema, &mut value).unwrap();
61//! assert!(result.is_valid());
62//! assert_eq!(value["tin"], json!("123456789")); // Transformed
63//! ```
64//!
65//! See <https://wellformed.net/docs/rust-runtime> for Rust runtime usage.
66
67pub mod codegen;
68pub mod error;
69pub mod form;
70#[cfg(test)]
71mod interop_test;
72pub mod ir;
73pub mod path;
74pub mod runtime;
75
76// Re-export commonly used types at the crate root
77pub use error::{Result, WelError};
78pub use form::{
79    ClientFormSpec, EmbeddedSchema, FieldKind, FieldSpec, FieldState, FormErrors, FormState,
80};
81pub use ir::{
82    Constraint, ErrorMeta, ErrorSeverity, FormError, Predicate, Schema, Transform, TypeSchema,
83};
84pub use path::{JsonPointer, Segment};
85pub use runtime::{validate, validate_with_registry, ValidationResult};
86
87// Address feature re-exports
88#[cfg(feature = "address")]
89pub use runtime::register_address_predicates;