1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! `scheme` — Fluent, type-safe JSON Schema builder.
//!
//! WHY: Constructing JSON Schema documents with `serde_json::json!` is verbose
//! and error-prone — you can set `.format("email")` on an integer schema, and
//! typos in keyword names are caught only at runtime. This module provides
//! type-specific builders where only valid methods are available.
//!
//! WHAT: Builder structs for each JSON Schema type (string, integer, object,
//! array, etc.) with type-specific constraint methods.
//!
//! HOW: Each builder accumulates JSON Schema properties in a `BTreeMap`.
//! `.build_schema()` returns the `serde_json::Value`. `.build()` returns
//! a `ValidationOptions` with the schema embedded, ready to chain into
//! `.compile()` for immediate validation.
//!
//! # Examples
//!
//! ## Direct pipeline: build → compile → validate
//!
//! ```
//! use foundation_jsonschema::scheme;
//!
//! let validator = scheme::object()
//! .required("name", scheme::string().min_len(1))
//! .required("age", scheme::integer().min(0).max(150))
//! .strict()
//! .build()
//! .compile()
//! .unwrap();
//!
//! let ok = validator.is_valid(&serde_json::json!({"name": "Alice", "age": 30}));
//! assert!(ok);
//! ```
//!
//! ## Extract raw JSON Schema
//!
//! ```
//! use foundation_jsonschema::scheme;
//!
//! let schema = scheme::string().min_len(1).max_len(100).build_schema();
//! assert_eq!(schema["minLength"], 1);
//! assert_eq!(schema["maxLength"], 100);
//! ```
//!
//! ## User profile schema with optional fields
//!
//! ```
//! use foundation_jsonschema::scheme;
//!
//! let validator = scheme::object()
//! .required("username", scheme::string().min_len(3).max_len(32))
//! .required("email", scheme::string().email())
//! .optional("bio", scheme::string().max_len(500))
//! .optional("avatar_url", scheme::string().uri().nullable())
//! .strict()
//! .build()
//! .compile()
//! .unwrap();
//!
//! // Minimal user (only required fields)
//! assert!(validator.is_valid(&serde_json::json!({
//! "username": "alice",
//! "email": "alice@example.com"
//! })));
//!
//! // Full user with optional fields
//! assert!(validator.is_valid(&serde_json::json!({
//! "username": "alice",
//! "email": "alice@example.com",
//! "bio": "Hello world"
//! })));
//! ```
//!
//! ## Coordinate tuple (fixed-length array)
//!
//! ```
//! use foundation_jsonschema::scheme;
//!
//! let schema = scheme::array()
//! .prefix_items(vec![
//! scheme::number().build_schema(), // x
//! scheme::number().build_schema(), // y
//! scheme::number().build_schema(), // z
//! ])
//! .build_schema();
//!
//! assert_eq!(schema["prefixItems"].as_array().unwrap().len(), 3);
//! ```
//!
//! ## Discriminated union (oneOf with const discriminator)
//!
//! ```
//! use foundation_jsonschema::{scheme, ValidationOptions};
//! use serde_json::json;
//!
//! let schema = scheme::one_of(vec![
//! scheme::object()
//! .required("type", scheme::literal(json!("circle")))
//! .required("radius", scheme::number().positive())
//! .strict()
//! .build_schema(),
//! scheme::object()
//! .required("type", scheme::literal(json!("rectangle")))
//! .required("width", scheme::number().positive())
//! .required("height", scheme::number().positive())
//! .strict()
//! .build_schema(),
//! ]);
//!
//! let validator = ValidationOptions::new().build(&schema).unwrap();
//!
//! assert!(validator.is_valid(&json!({"type": "circle", "radius": 5.0})));
//! assert!(validator.is_valid(&json!({"type": "rectangle", "width": 3.0, "height": 4.0})));
//! assert!(!validator.is_valid(&json!({"type": "circle", "width": 3.0})));
//! ```
pub use ;
pub use ;
pub use ;
pub use ;
pub use *;
pub use ;
// Re-export for type signatures — users rarely need this directly.
pub use crateValidationOptions;
use BTreeMap;
use Value;