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
//! Hash validation utilities for `libvctrl_core`.
//!
//! # Purpose
//!
//! This module provides utility functions to validate the structural integrity
//! of raw cryptographic hashes before they are converted into strongly-typed
//! [`Hash`](libvctrl_handler::Hash) objects. The single exported function,
//! [`validate_hash_bytes`], ensures that any byte slice intended to represent
//! a hash has exactly the required length.
//!
//! # Design Rationale
//!
//! - **Early failure**: By validating the byte length before attempting to
//! construct a [`Hash`](libvctrl_handler::Hash), the system fails fast and
//! provides clear error messages, preventing panics in downstream code.
//! - **Compile-time capability**: The validation function is a `const fn`,
//! allowing it to be used in `const` evaluation contexts to verify static
//! hash arrays at compile time. This is useful for checking hardcoded
//! hashes in configuration or test vectors without runtime overhead.
//! - **Decoupling**: This logic is separated from the `Hash` constructor
//! itself to keep the data type pure and allow callers to perform
//! pre-checks if they are interacting with untrusted byte streams.
//! - **Reusability**: Other modules can call this validator before constructing
//! a [`Hash`](libvctrl_handler::Hash) to provide custom error handling,
//! logging, or context without repeating the length check.
//!
//! # Relationship to `libvctrl_handler`
//!
//! The [`Hash`](libvctrl_handler::Hash) type in `libvctrl_handler` already
//! performs its own validation inside
//! [`Hash::from_bytes`](libvctrl_handler::Hash::from_bytes). This module does
//! not replace that internal check; rather, it exposes the same invariant as
//! a standalone function. This allows callers to validate data *before*
//! entering a context where constructing a `Hash` would otherwise fail, or
//! where they want a more explicit control flow.
//!
//! # Security Considerations
//!
//! The function only checks the length of the byte slice. It does not verify
//! the cryptographic strength or origin of the bytes. For content-addressing
//! purposes, the caller is responsible for obtaining the hash from a trusted
//! source or computing it via a [`Hasher`](libvctrl_handler::Hasher). This
//! validator acts as the first structural gate, not as a cryptographic
//! guarantee.
//!
//! # Performance
//!
//! The function performs an O(1) comparison between the slice length and the
//! constant [`HASH_LENGTH`](libvctrl_handler::HASH_LENGTH). It does not
//! iterate over the bytes or allocate any memory. In a `const` context, the
//! check is evaluated entirely at compile time, producing zero runtime cost.
//!
//! # When to Use
//!
//! - Before calling [`Hash::from_bytes`](libvctrl_handler::Hash::from_bytes)
//! when you want a custom error path or need to log the specific invalid
//! length.
//! - Inside parsers or decoders that read hashes from a binary format and
//! want to validate fields incrementally.
//! - In `const` contexts where a static hash must be verified to have the
//! correct length before use.
//!
//! # Examples
//!
//! Validating a correctly sized slice:
//!
//! ```
//! use libvctrl_core::validate::hash::validate_hash_bytes;
//! use libvctrl_handler::HASH_LENGTH;
//!
//! let valid_bytes = [0u8; HASH_LENGTH];
//! assert!(validate_hash_bytes(&valid_bytes).is_ok());
//! ```
//!
//! Validating an incorrectly sized slice:
//!
//! ```
//! use libvctrl_core::validate::hash::validate_hash_bytes;
//! use libvctrl_handler::VctrlError;
//!
//! let invalid_bytes = [0u8; 32];
//! let result = validate_hash_bytes(&invalid_bytes);
//!
//! assert!(matches!(result, Err(VctrlError::InvalidHashLength(32))));
//! ```
use ;
/// Validates that a byte slice is exactly [`HASH_LENGTH`] bytes long.
///
/// # Purpose
///
/// This function acts as a gatekeeper to ensure that any byte slice intended
/// to represent a [`Hash`](libvctrl_handler::Hash) meets the strict length
/// invariant (64 bytes) required by the system. It returns `Ok(())` if the
/// length is correct, or an error describing the mismatch otherwise.
///
/// # Design Rationale
///
/// - **`const fn`**: Being a `const fn` allows this check to be evaluated
/// during compilation if the inputs are known constants. This is useful for
/// verifying hardcoded hashes in configuration or test vectors.
/// - **Pre-conditions check**: It is often used as a pre-check before calling
/// [`Hash::from_bytes`](libvctrl_handler::Hash::from_bytes) to provide
/// custom error handling or logging before the actual conversion.
/// - **Single responsibility**: The function performs exactly one check and
/// does not attempt to construct a [`Hash`](libvctrl_handler::Hash). This
/// keeps the logic simple and composable.
///
/// # Internal Mechanism
///
/// The function compares the length of the provided slice to the constant
/// [`HASH_LENGTH`](libvctrl_handler::HASH_LENGTH). If the lengths differ, it
/// returns [`VctrlError::InvalidHashLength`] containing the actual length.
/// The comparison and branch are trivial and compile to a handful of CPU
/// instructions.
///
/// # Errors
///
/// Returns
/// [`VctrlError::InvalidHashLength`](libvctrl_handler::VctrlError::InvalidHashLength)
/// if the length of `bytes` is not exactly equal to
/// [`HASH_LENGTH`](libvctrl_handler::HASH_LENGTH) (64). The error payload is
/// the actual length of the input slice, allowing callers to report the
/// mismatch precisely.
///
/// # Panics
///
/// This function never panics. It handles all possible inputs gracefully by
/// returning a [`Result`].
///
/// # Examples
///
/// Validating a correctly sized slice:
///
/// ```
/// use libvctrl_core::validate::hash::validate_hash_bytes;
/// use libvctrl_handler::HASH_LENGTH;
///
/// let valid_bytes = [0u8; HASH_LENGTH];
/// assert!(validate_hash_bytes(&valid_bytes).is_ok());
/// ```
///
/// Validating an incorrectly sized slice:
///
/// ```
/// use libvctrl_core::validate::hash::validate_hash_bytes;
/// use libvctrl_handler::VctrlError;
///
/// let invalid_bytes = [0u8; 32];
/// let result = validate_hash_bytes(&invalid_bytes);
///
/// assert!(matches!(result, Err(VctrlError::InvalidHashLength(32))));
/// ```
pub const