Skip to main content

qubit_validator/registry/
validator_signature.rs

1// =============================================================================
2//    Copyright (c) 2025 - 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8
9//! Input and dependency signatures for validator definitions.
10
11use std::fmt::Debug;
12use std::fmt::Formatter;
13use std::fmt::Result as FmtResult;
14
15use crate::binding::DependencySpec;
16use crate::binding::InputType;
17use crate::binding::PrepareFn;
18
19/// One statically declared way to bind a validator.
20///
21/// # Examples
22///
23/// ```
24/// use std::sync::Arc;
25///
26/// use qubit_validator::ArgumentReader;
27/// use qubit_validator::BindError;
28/// use qubit_validator::BoundValidationContext;
29/// use qubit_validator::DependencySpec;
30/// use qubit_validator::ExecutionError;
31/// use qubit_validator::InputType;
32/// use qubit_validator::PreparedOutcome;
33/// use qubit_validator::PreparedValidator;
34/// use qubit_validator::ValidationValue;
35/// use qubit_validator::ValidatorSignature;
36///
37/// struct Accept;
38/// impl PreparedValidator for Accept {
39///     fn input_type(&self) -> InputType { InputType::Text }
40///     fn dependency_specs(&self) -> &'static [DependencySpec] { &[] }
41///     fn validate(
42///         &self,
43///         _: ValidationValue<'_>,
44///         _: &BoundValidationContext<'_>,
45///     ) -> Result<PreparedOutcome, ExecutionError> {
46///         Ok(PreparedOutcome::valid())
47///     }
48/// }
49/// fn prepare(_reader: &mut ArgumentReader<'_>) -> Result<Arc<dyn PreparedValidator>, BindError> {
50///     Ok(Arc::new(Accept))
51/// }
52///
53/// let signature = ValidatorSignature::new(InputType::Text, &[], prepare);
54/// assert_eq!(signature.input(), InputType::Text);
55/// assert!(signature.dependencies().is_empty());
56/// ```
57#[derive(Clone, Copy)]
58pub struct ValidatorSignature {
59    /// Erased input shape accepted by this signature.
60    input: InputType,
61    /// Ordered dependency slots required by the prepared validator.
62    dependencies: &'static [DependencySpec],
63    /// Factory which decodes parameters and creates the prepared validator.
64    prepare: PrepareFn,
65}
66
67impl ValidatorSignature {
68    /// Creates a signature with ordered dependency slots.
69    ///
70    /// # Parameters
71    ///
72    /// - `input`: Erased input shape accepted by the validator.
73    /// - `dependencies`: Dependency slots passed to the prepared validator, in
74    ///   order.
75    /// - `prepare`: Function that binds arguments and creates the prepared
76    ///   validator.
77    ///
78    /// # Returns
79    ///
80    /// A signature containing the supplied input shape, dependencies, and
81    /// factory.
82    #[must_use]
83    #[inline]
84    pub const fn new(input: InputType, dependencies: &'static [DependencySpec], prepare: PrepareFn) -> Self {
85        Self {
86            input,
87            dependencies,
88            prepare,
89        }
90    }
91
92    /// Returns the accepted value shape.
93    ///
94    /// # Returns
95    ///
96    /// The erased input shape this signature accepts.
97    #[must_use]
98    #[inline]
99    pub const fn input(self) -> InputType {
100        self.input
101    }
102
103    /// Returns dependency declarations in slot order.
104    ///
105    /// # Returns
106    ///
107    /// The static dependency slice in the order passed to the prepared
108    /// validator.
109    #[must_use]
110    #[inline]
111    pub const fn dependencies(self) -> &'static [DependencySpec] {
112        self.dependencies
113    }
114
115    /// Returns the parameter binding function.
116    ///
117    /// # Returns
118    ///
119    /// The factory function that binds parameters and creates the prepared
120    /// validator.
121    #[must_use]
122    #[inline]
123    pub const fn prepare(self) -> PrepareFn {
124        self.prepare
125    }
126}
127
128impl Debug for ValidatorSignature {
129    /// Formats the input shape and dependency count without invoking the
130    /// factory.
131    ///
132    /// # Parameters
133    ///
134    /// - `formatter`: Destination that receives the debug representation.
135    fn fmt(&self, formatter: &mut Formatter<'_>) -> FmtResult {
136        formatter
137            .debug_struct("ValidatorSignature")
138            .field("input", &self.input)
139            .field("dependency_count", &self.dependencies.len())
140            .finish()
141    }
142}