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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
//! The unified error type for the entire `libvctrl` ecosystem.
//!
//! This module provides [`VctrlError`], the **single error type** that every
//! fallible operation in `libvctrl` must return. By having one error type we
//! guarantee that errors are explicit, predictable, and can never be silently
//! ignored.
//!
//! # Design principles
//!
//! - **Exhaustive** – every possible failure (validation, storage, corruption,
//! I/O, serialisation) is covered by a dedicated variant.
//! - **Object‑safe** – the error type is `Clone + Eq + 'static` and implements
//! [`std::error::Error`]; it can be used in dynamic contexts without boxing.
//! - **No platform coupling** – I/O and transport errors are stored as a plain
//! `String` so that the handler crate remains `#![no_std]` compatible (when
//! built without `std`) and does not depend on `std::io::Error`.
//! - **Forward‑compatible** – the `#[non_exhaustive]` attribute and the
//! [`Other`](VctrlError::Other) fallback variant mean that new error kinds
//! can be added in minor releases without breaking existing code.
//!
//! # Usage
//!
//! ```rust
//! use libvctrl_handler::{Hash, VctrlError, HASH_LENGTH};
//!
//! // Construct errors directly ...
//! let bad_hash = VctrlError::InvalidHashLength(10);
//! let not_found = VctrlError::ObjectNotFound(
//! Hash::from_bytes(&[0u8; HASH_LENGTH]).unwrap()
//! );
//!
//! // ... or use the convenience macro
//! let custom = libvctrl_handler::vctrl_error_other!("something broke: {}", 42);
//! assert_eq!(custom.to_string(), "something broke: 42");
//! ```
use crateHash;
use fmt;
/// Represents every possible error that can occur within `libvctrl`.
///
/// Every fallible public API in the workspace returns `Result<T, VctrlError>`.
/// This enum is **the** contract for error handling – no other error type
/// should leak across crate boundaries.
///
/// # When to use which variant
///
/// | Situation | Variant |
/// |---|---|
/// | A byte slice that should be a hash has the wrong length | [`InvalidHashLength`](Self::InvalidHashLength) |
/// | A name (file, reference, user, tag) is empty or too long | [`InvalidName`](Self::InvalidName) |
/// | An object hash is not in the store | [`ObjectNotFound`](Self::ObjectNotFound) |
/// | A reference name is not in the ref store | [`RefNotFound`](Self::RefNotFound) |
/// | Stored data is truncated, has bad magic bytes, or is otherwise unreadable | [`CorruptedData`](Self::CorruptedData) |
/// | A real I/O operation failed (disk full, permission denied, etc.) | [`IoError`](Self::IoError) |
/// | An encoder/decoder cannot process a value | [`SerializationError`](Self::SerializationError) |
/// | Any error that does not fit the above categories | [`Other`](Self::Other) |
///
/// # Display
///
/// The [`Display`](std::fmt::Display) implementation produces human‑readable
/// messages that include relevant detail (hash value, name, etc.). These
/// messages are **not** guaranteed to be stable across versions; they are
/// intended for developers, not for programmatic matching.
///
/// # Stability
///
/// `VctrlError` is `#[non_exhaustive]`. Pattern‑matching on its variants
/// requires a wildcard arm. This allows us to add new error kinds without a
/// semver‑breaking change.
///
/// # Example
///
/// ```rust
/// use libvctrl_handler::{Hash, VctrlError, HASH_LENGTH};
///
/// let hash = Hash::from_bytes(&[0u8; HASH_LENGTH]).unwrap();
/// let err = VctrlError::ObjectNotFound(hash);
/// println!("{err}"); // "Object not found: 0000000000000000..."
/// ```