qubit_argument/argument/argument_error_kind.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//! Structured kinds of argument validation failure.
9
10use crate::argument::ArgumentValue;
11use crate::argument::ComparisonConstraint;
12use crate::argument::IndexRole;
13use crate::argument::LengthConstraint;
14use crate::argument::LengthMetric;
15use crate::argument::PatternExpectation;
16use crate::argument::RangeConstraint;
17
18/// Identifies the validation rule that an argument failed.
19///
20/// Each variant stores only structured context needed to inspect and format
21/// the failure. Validated string contents are never captured implicitly.
22///
23/// # Examples
24///
25/// ```
26/// use qubit_argument::ArgumentErrorKind;
27///
28/// let error = ArgumentErrorKind::Missing;
29/// assert!(matches!(error, ArgumentErrorKind::Missing));
30/// ```
31///
32/// ```compile_fail
33/// #![deny(unused_must_use)]
34/// use qubit_argument::ArgumentErrorKind;
35///
36/// ArgumentErrorKind::Missing;
37/// ```
38#[non_exhaustive]
39#[must_use]
40#[derive(Debug, Clone, PartialEq, Eq)]
41pub enum ArgumentErrorKind {
42 /// The required argument was absent.
43 Missing,
44 /// The string argument contained no non-whitespace characters.
45 Blank,
46 /// The collection argument was empty.
47 Empty,
48 /// The argument length did not satisfy a length constraint.
49 Length {
50 /// The observed length in the unit identified by `metric`.
51 actual: usize,
52 /// The required length relationship.
53 constraint: LengthConstraint,
54 /// The unit used to measure the observed and required lengths.
55 metric: LengthMetric,
56 },
57 /// A scalar argument did not satisfy a comparison constraint.
58 Comparison {
59 /// The observed numeric or duration value.
60 actual: ArgumentValue,
61 /// The required comparison relationship.
62 constraint: ComparisonConstraint,
63 },
64 /// The numeric argument was outside a required range.
65 Range {
66 /// The observed numeric value.
67 actual: ArgumentValue,
68 /// The required range.
69 constraint: RangeConstraint,
70 },
71 /// The supplied length constraint was internally invalid.
72 InvalidLengthConstraint {
73 /// The invalid length constraint.
74 constraint: LengthConstraint,
75 /// The unit to which the invalid constraint would have applied.
76 metric: LengthMetric,
77 },
78 /// The supplied numeric range was internally invalid.
79 InvalidRangeConstraint {
80 /// The invalid numeric range.
81 constraint: RangeConstraint,
82 },
83 /// The argument or numeric constraint contained a floating-point NaN value.
84 NotANumber,
85 /// The floating-point argument was positive or negative infinity.
86 NotFinite {
87 /// The rejected infinite floating-point value.
88 actual: ArgumentValue,
89 },
90 /// An element or position index was outside its valid domain.
91 Index {
92 /// The rejected index.
93 index: usize,
94 /// The collection size used for validation.
95 size: usize,
96 /// Whether the index identifies an element or a position.
97 role: IndexRole,
98 },
99 /// A position range was invalid for a collection size.
100 IndexRange {
101 /// The inclusive start position.
102 start: usize,
103 /// The exclusive end position.
104 end: usize,
105 /// The collection size used for validation.
106 size: usize,
107 },
108 /// An offset and length did not fit within a total length.
109 Bounds {
110 /// The rejected starting offset.
111 offset: usize,
112 /// The rejected span length.
113 length: usize,
114 /// The available total length.
115 total_length: usize,
116 },
117 /// A string did not satisfy a pattern expectation.
118 Pattern {
119 /// The pattern text used for validation.
120 pattern: String,
121 /// Whether a match or non-match was required.
122 expectation: PatternExpectation,
123 },
124 /// A caller-defined validation rule failed.
125 Custom {
126 /// A machine-readable caller-defined code.
127 code: String,
128 /// A human-readable caller-defined explanation.
129 message: String,
130 },
131}