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