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
//! 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
//! (e.g., 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. However, `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. By using `#![warn(clippy::nursery)]`
//! we keep the lints visible in CI output without breaking the build for
//! contributors who use a slightly different compiler version. Individual
//! nursery lints that are considered critical (e.g., `missing_const_for_fn`)
//! can still be explicitly denied.
//!
//! # Internal Mechanism
//!
//! The crate exports all public types, traits, and constants at the root level
//! for convenience. Consumers can simply `use libvctrl_handler::*;` to access
//! the entire contract surface. The re-exports are organized to 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`] (e.g., [`Hasher`], [`ObjectStore`]) are re-exported.
//! - Data types from [`types`] (e.g., [`Blob`], [`Commit`], [`Hash`]) are re-exported.
//!
//! This flat namespace is ideal for a contract crate, as 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 module-level documentation for rationale.
/// System-wide constants and structural limits used across the version control
/// system.
///
/// # Purpose
///
/// This module centralises all numeric constants (e.g., [`HASH_LENGTH`],
/// [`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 doc comment and 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 [`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;
/// use std::error::Error;
/// 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
/// [`VctrlError::Other`] variants with formatted messages, mimicking the
/// `format!` syntax.
///
/// # Examples
///
/// ```
/// use libvctrl_handler::VctrlError;
/// use libvctrl_handler::vctrl_error_other;
///
/// let err: VctrlError = 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**:
///
/// - [`ObjectStore`] handles object retrieval and storage.
/// - [`RefStore`] manages named references (branches, tags).
/// - [`Hasher`] computes cryptographic hashes.
/// - [`Encoder`] / [`Decoder`] serialise and deserialise objects.
/// - [`Signer`] / [`Verifier`] handle digital signatures.
/// - [`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 [`Hasher`]:
///
/// ```
/// use libvctrl_handler::traits::Hasher;
/// use libvctrl_handler::Hash;
/// use libvctrl_handler::errors::VctrlError;
/// use std::error::Error;
///
/// struct DummyHasher;
/// impl Hasher for DummyHasher {
/// fn hash(&self, _data: &[u8]) -> Hash {
/// Hash::from_bytes(&[0u8; 64]).unwrap()
/// }
/// }
///
/// let hasher = DummyHasher;
/// let h = hasher.hash(b"hello");
/// assert_eq!(h.as_bytes().len(), 64);
/// ```
/// Core data structures representing version control objects.
///
/// # Purpose
///
/// The [`types`] module contains all the domain models: [`Blob`], [`Tree`],
/// [`Commit`], [`Tag`], and supporting types like [`Hash`] and [`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:
///
/// - [`ObjectStore`]
/// - [`RefStore`]
/// - [`Hasher`]
/// - [`Encoder`] / [`Decoder`]
/// - [`Signer`] / [`Verifier`]
/// - [`Transport`]
///
/// # Examples
///
/// ```
/// use libvctrl_handler::{Hasher, Hash};
///
/// struct MyHasher;
/// impl Hasher for MyHasher {
/// fn hash(&self, _data: &[u8]) -> Hash {
/// Hash::from_bytes(&[0u8; 64]).unwrap()
/// }
/// }
/// ```
pub use ;
/// Re-exports of the core data structures.
///
/// All version-control objects ([`Blob`], [`Tree`], [`Commit`], [`Tag`]) and
/// their supporting types ([`Hash`], [`UserID`], [`CommitMeta`],
/// [`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 ;