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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// =============================================================================
// Copyright (c) 2025 - 2026 Haixing Hu.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0.
// =============================================================================
//! Type-erased prepared validator instances.
use Arc;
use ArgumentReader;
use BindError;
use BoundValidationContext;
use DependencySpec;
use ExecutionError;
use InputType;
use PreparedOutcome;
use ValidationValue;
/// A configured, immutable validator instance safe to share between calls.
///
/// Direct calls are a lower-level execution path. The caller must supply a
/// target matching [`Self::input_type`] and a context matching
/// [`Self::dependency_specs`] in count, order, type, and optional-value
/// representation. When dependency paths are provided, they must correspond
/// to the value slots. Constructing a [`BoundValidationContext`] does not
/// validate it against these declarations.
///
/// This layer does not interpret error paths or add a target prefix. When
/// integrated with model validation, ordinary rule errors use target-relative
/// paths; an error for a dependency should name a declared slot and use that
/// dependency's coordinate system. Model navigation and final path handling
/// belong to the integrating layer.
///
/// For configured execution, bind through a [`crate::ValidatorDescriptor`] or
/// [`crate::ValidatorRegistry`] and call [`crate::BoundValidator::validate`].
/// That boundary checks the declared shapes and outcome invariants and attaches
/// the bound rule ID to violation drafts. A direct call returns a
/// [`PreparedOutcome`] whose drafts do not yet carry the bound rule ID. Custom
/// implementations must document any further preconditions rather than assuming
/// the bound boundary has already run.
///
/// The direct-call example below uses a matching text target and no
/// dependencies.
///
/// # Examples
///
/// ```
/// use std::sync::Arc;
///
/// use qubit_validator::{
/// BoundValidationContext, ExecutionError, PreparedOutcome, PreparedValidator,
/// ValidationValue,
/// };
///
/// struct Accept;
/// impl PreparedValidator for Accept {
/// fn input_type(&self) -> qubit_validator::InputType {
/// qubit_validator::InputType::Text
/// }
///
/// fn dependency_specs(&self) -> &'static [qubit_validator::DependencySpec] {
/// &[]
/// }
///
/// fn validate(
/// &self,
/// _: ValidationValue<'_>,
/// _: &BoundValidationContext<'_>,
/// ) -> Result<PreparedOutcome, ExecutionError> {
/// Ok(PreparedOutcome::valid())
/// }
/// }
///
/// let prepared: Arc<dyn PreparedValidator> = Arc::new(Accept);
/// let result = prepared.validate(
/// ValidationValue::Text("ready"),
/// &BoundValidationContext::new(&[]),
/// );
/// assert_eq!(result?, PreparedOutcome::valid());
/// # Ok::<(), ExecutionError>(())
/// ```
/// Constructs an owned prepared validator from declaration parameters.
///
/// When binding through a descriptor or registry, the binding layer rejects
/// duplicate parameter names before calling the factory and rejects unconsumed
/// parameters after it returns. The factory's reader calls decide which
/// parameters are required and reject invalid types or ranges. Calling the
/// factory directly does not provide the binding layer's checks.
///
/// # Examples
///
/// ```
/// use std::sync::Arc;
///
/// use qubit_validator::{
/// ArgumentReader, BindError, BoundValidationContext, ExecutionError,
/// PrepareFn, PreparedOutcome, PreparedValidator, ValidationValue,
/// };
///
/// struct Accept;
/// impl PreparedValidator for Accept {
/// fn input_type(&self) -> qubit_validator::InputType {
/// qubit_validator::InputType::Text
/// }
///
/// fn dependency_specs(&self) -> &'static [qubit_validator::DependencySpec] {
/// &[]
/// }
///
/// fn validate(
/// &self,
/// _: ValidationValue<'_>,
/// _: &BoundValidationContext<'_>,
/// ) -> Result<PreparedOutcome, ExecutionError> {
/// Ok(PreparedOutcome::valid())
/// }
/// }
///
/// fn prepare(_reader: &mut ArgumentReader<'_>) -> Result<Arc<dyn PreparedValidator>, BindError> {
/// Ok(Arc::new(Accept))
/// }
///
/// let factory: PrepareFn = prepare;
/// let mut reader = ArgumentReader::new(&[])?;
/// let prepared = factory(&mut reader)?;
/// reader.finish()?;
/// assert_eq!(prepared.validate(
/// ValidationValue::Text("ready"),
/// &BoundValidationContext::new(&[]),
/// )?, PreparedOutcome::valid());
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
pub type PrepareFn = for<'a> fn ;