qubit_validator/binding/named_validation_dependency.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//! Named borrowed dependency values for direct bound-validator calls.
10
11use std::fmt::Debug;
12use std::fmt::Formatter;
13use std::fmt::Result;
14
15use crate::ValidationPath;
16use crate::ValidationValue;
17
18/// One dependency value identified by its signature name.
19///
20/// Names come from the validator declaration. Values and paths remain borrowed
21/// for the validation call and are never retained by the binding. An optional
22/// path is caller-selected and remains attached to its named slot when inputs
23/// are reordered; it is not prefixed with the current target path.
24///
25/// # Type Parameters
26///
27/// - `'a`: Lifetime shared by the borrowed value and optional path.
28///
29/// # Examples
30///
31/// ```
32/// use qubit_validator::{NamedValidationDependency, ValidationValue};
33///
34/// let dependency = NamedValidationDependency::new("email", ValidationValue::Text("a@example.test"));
35/// assert!(!format!("{dependency:?}").contains("a@example.test"));
36/// ```
37#[derive(Clone, Copy)]
38pub struct NamedValidationDependency<'a> {
39 /// Static name declared by the selected validator signature.
40 pub(super) name: &'static str,
41 /// Borrowed value supplied for the dependency slot.
42 pub(super) value: ValidationValue<'a>,
43 /// Optional location used in structured dependency errors.
44 pub(super) path: Option<&'a ValidationPath>,
45}
46
47impl<'a> NamedValidationDependency<'a> {
48 /// Creates a named dependency value without a specific path.
49 ///
50 /// # Parameters
51 /// - `name`: Static name from the validator signature.
52 /// - `value`: Borrowed value for the dependency.
53 ///
54 /// # Returns
55 /// A named borrowed dependency with no associated path.
56 #[must_use]
57 #[inline]
58 pub const fn new(name: &'static str, value: ValidationValue<'a>) -> Self {
59 Self {
60 name,
61 value,
62 path: None,
63 }
64 }
65
66 /// Associates a caller-supplied path with this dependency value.
67 ///
68 /// The path is kept unchanged and follows this named slot if
69 /// [`crate::BoundValidator::validate_named`] reorders the inputs. This
70 /// method does not add a current-target prefix.
71 ///
72 /// # Parameters
73 /// - `path`: Borrowed path identifying the dependency in the coordinate
74 /// system selected by the caller.
75 ///
76 /// # Returns
77 /// The dependency associated with `path`.
78 #[must_use]
79 #[inline]
80 pub const fn with_path(mut self, path: &'a ValidationPath) -> Self {
81 self.path = Some(path);
82 self
83 }
84}
85
86impl Debug for NamedValidationDependency<'_> {
87 /// Formats only dependency shape without exposing values or paths.
88 fn fmt(&self, formatter: &mut Formatter<'_>) -> Result {
89 formatter
90 .debug_struct("NamedValidationDependency")
91 .field("has_path", &self.path.is_some())
92 .finish_non_exhaustive()
93 }
94}