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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
//! Fundamental contracts for building a version control system.
//!
//! # Purpose
//!
//! `libvctrl_handler` provides the core, pure-data types and behavior traits
//! required to construct a version control system (VCS). It intentionally
//! contains no implementations, only the abstract definitions of objects
//! (blobs, trees, commits, tags) and the interfaces for storing, hashing,
//! encoding, and transporting them.
//!
//! # Design Rationale
//!
//! The crate enforces a strict separation between data and behavior:
//!
//! - Data is represented by immutable structs in [`types`].
//! - Behavior is defined by traits in [`traits`].
//!
//! This decoupling allows downstream applications to mix and match backends
//! (for example, an in-memory store with a binary encoder and Ed25519
//! signing) without altering the core domain logic.
//!
//! ## Lint policy
//!
//! The crate uses a strict set of compiler and Clippy lints to ensure high
//! code quality. `clippy::nursery` is configured as a warning rather than a
//! deny because nursery lints are unstable and can introduce new warnings
//! with Rust toolchain updates. Critical nursery lints can still be denied
//! individually if needed.
//!
//! # Internal Mechanism
//!
//! The crate exports all public types, traits, and constants at the root level
//! for convenience. Consumers can use `libvctrl_handler::*;` to access the
//! entire contract surface. The re-exports mirror the internal module
//! structure:
//!
//! - Constants from [`constants`] are re-exported directly.
//! - Enums from [`enums`] are re-exported as [`EntryKind`].
//! - Error types from [`errors`] are re-exported as [`VctrlError`].
//! - Traits from [`traits`] are re-exported (for example [`Hasher`] and
//! [`ObjectStore`]).
//! - Data types from [`types`] are re-exported (for example [`Blob`] and
//! [`Hash`]).
//!
//! This flat namespace is ideal for a contract crate because it eliminates
//! excessive qualification in downstream code while still allowing selective
//! imports.
//!
//! # Examples
//!
//! Constructing a basic object and hash:
//!
//! ```
//! use libvctrl_handler::{Blob, Hash};
//!
//! let blob = Blob::new(b"content".to_vec());
//! let hash = Hash::from_bytes(&[0u8; 64]).unwrap();
//! assert_eq!(blob.size(), 7);
//! assert_eq!(hash.as_bytes().len(), 64);
//! ```
// Nursery lints are unstable; we only warn so that toolchain updates do not
// suddenly break the build. See crate-level documentation for rationale.
/// System-wide constants and structural limits used across the version control
/// system.
///
/// # Purpose
///
/// This module centralizes all numeric constants (for example [`HASH_LENGTH`]
/// and [`MAX_NAME_LENGTH`]) so that they can be used consistently by every
/// other module and by downstream crates. Changing a constant here
/// automatically propagates to all dependent code.
///
/// # Why a separate module
///
/// Grouping constants in one module avoids circular dependencies and keeps
/// the root namespace clean. It also makes it easy to document each constant
/// with its own doctest.
///
/// # Examples
///
/// ```
/// use libvctrl_handler::constants::HASH_LENGTH;
/// assert_eq!(HASH_LENGTH, 64);
/// ```
/// Logical object type enumerations, distinguishing between files and
/// directories.
///
/// # Purpose
///
/// The [`EntryKind`] enum is used throughout the system to differentiate
/// between a file (blob) and a directory (tree). It is deliberately kept
/// small to facilitate exhaustive matching.
///
/// # Design note
///
/// By using a C-like enum (no data attached), we ensure [`EntryKind`] is
/// [`Copy`], lightweight, and easy to embed in other structures without
/// lifetime concerns.
///
/// # Examples
///
/// ```
/// use libvctrl_handler::enums::EntryKind;
/// assert_ne!(EntryKind::Blob, EntryKind::Tree);
/// ```
/// Unified error handling for all fallible operations within the crate.
///
/// # Purpose
///
/// The [`errors`] module exports the [`crate::VctrlError`] enum, which is the
/// single error type used by every trait method in this crate. This
/// unification simplifies error propagation and pattern matching for
/// consumers.
///
/// # Examples
///
/// ```
/// use libvctrl_handler::errors::VctrlError;
///
/// let err = VctrlError::Other("fail".to_string());
/// assert_eq!(err.to_string(), "fail");
/// ```
/// Helper macros for ergonomic error construction.
///
/// # Purpose
///
/// The `vctrl_error_other!` macro provides a concise way to create
/// [`crate::VctrlError::Other`] variants with formatted messages, mimicking
/// the `format!` syntax.
///
/// # Examples
///
/// ```
/// use libvctrl_handler::vctrl_error_other;
///
/// let err = vctrl_error_other!("code {}", 500);
/// assert_eq!(err.to_string(), "code 500");
/// ```
/// Core behavior contracts (traits) for storage, encoding, hashing, and
/// transport.
///
/// # Purpose
///
/// This module defines the interfaces that any concrete backend must
/// implement. By depending only on these traits, the core logic remains
/// completely decoupled from specific storage engines, hash algorithms, or
/// network transports.
///
/// # Design Rationale
///
/// Every trait follows the single responsibility principle:
///
/// - [`crate::ObjectStore`] handles object retrieval and storage.
/// - [`crate::RefStore`] manages named references (branches, tags).
/// - [`crate::Hasher`] computes cryptographic hashes.
/// - [`crate::Encoder`] and [`crate::Decoder`] serialize and deserialize objects.
/// - [`crate::Signer`] and [`crate::Verifier`] handle digital signatures.
/// - [`crate::Transport`] abstracts the network layer.
///
/// This separation allows a user to swap, for example, the hash algorithm
/// without touching any other component.
///
/// # Examples
///
/// Implementing a dummy [`crate::Hasher`]:
///
/// ```
/// use libvctrl_handler::{Hash, Hasher, VctrlError};
///
/// struct DummyHasher;
///
/// impl Hasher for DummyHasher {
/// fn hash(&self, _data: &[u8]) -> Result<Hash, VctrlError> {
/// Ok(Hash::from_bytes(&[0u8; 64]).unwrap())
/// }
/// }
///
/// let hasher = DummyHasher;
/// let hash = hasher.hash(b"hello").unwrap();
/// assert_eq!(hash.as_bytes().len(), 64);
/// ```
/// Core data structures representing version control objects.
///
/// # Purpose
///
/// The [`types`] module contains all the domain models: [`crate::Blob`],
/// [`crate::Tree`], [`crate::Commit`], [`crate::Tag`], and supporting types
/// like [`crate::Hash`] and [`crate::UserID`]. These structs are intentionally
/// immutable after construction to simplify reasoning about state and to
/// guarantee thread safety.
///
/// # Examples
///
/// ```
/// use libvctrl_handler::types::Blob;
///
/// let blob = Blob::new(vec![1, 2, 3]);
/// assert_eq!(blob.size(), 3);
/// ```
/// Re-exports of fundamental system constants like [`HASH_LENGTH`] and
/// maximum size limits.
///
/// # Purpose
///
/// These constants are used so frequently that they are re-exported at the
/// crate root. This saves the caller from having to write
/// `libvctrl_handler::constants::HASH_LENGTH` everywhere.
///
/// # Examples
///
/// ```
/// use libvctrl_handler::HASH_LENGTH;
/// assert_eq!(HASH_LENGTH, 64);
/// ```
pub use ;
/// Re-export of the [`EntryKind`] enum.
///
/// [`EntryKind`] is the only public enum in the crate, and re-exporting it
/// at the root reinforces its role as a fundamental building block.
///
/// # Examples
///
/// ```
/// use libvctrl_handler::EntryKind;
/// assert_eq!(EntryKind::Blob, EntryKind::Blob);
/// ```
pub use EntryKind;
/// Re-export of the unified [`VctrlError`] type.
///
/// # Purpose
///
/// Every fallible operation in this crate returns `Result<_, VctrlError>`.
/// Making [`VctrlError`] available at the crate root streamlines error
/// handling for downstream code.
///
/// # Examples
///
/// ```
/// use libvctrl_handler::VctrlError;
///
/// let err = VctrlError::Other("test".to_string());
/// assert!(err.to_string().contains("test"));
/// ```
pub use VctrlError;
/// Re-exports of the core behavior traits.
///
/// This includes:
///
/// - [`crate::ObjectStore`]
/// - [`crate::RefStore`]
/// - [`crate::Hasher`]
/// - [`crate::Encoder`] and [`crate::Decoder`]
/// - [`crate::Signer`] and [`crate::Verifier`]
/// - [`crate::Transport`]
///
/// # Examples
///
/// ```
/// use libvctrl_handler::{Hash, Hasher, VctrlError};
///
/// struct MyHasher;
///
/// impl Hasher for MyHasher {
/// fn hash(&self, _data: &[u8]) -> Result<Hash, VctrlError> {
/// Ok(Hash::from_bytes(&[0u8; 64]).unwrap())
/// }
/// }
///
/// let hasher = MyHasher;
/// let hash = hasher.hash(b"data").unwrap();
/// assert_eq!(hash.as_bytes().len(), 64);
/// ```
pub use ;
/// Re-exports of the core data structures.
///
/// All version-control objects ([`crate::Blob`], [`crate::Tree`],
/// [`crate::Commit`], [`crate::Tag`]) and their supporting types
/// ([`crate::Hash`], [`crate::UserID`], [`crate::CommitMeta`],
/// [`crate::TreeEntry`]) are available directly from the crate root.
///
/// # Examples
///
/// ```
/// use libvctrl_handler::Blob;
///
/// let blob = Blob::new(vec![1, 2, 3]);
/// assert_eq!(blob.size(), 3);
/// ```
pub use ;