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
//! # Types
//!
//! Fundamental data types and name validation utilities for the version
//! control system.
//!
//! # Purpose
//!
//! This module is the canonical home for all domain model types used by
//! `libvctrl_handler`. It contains the core object types (blobs, trees,
//! commits, tags, hashes) and supporting identity types (user IDs), as well
//! as shared validation functions that enforce system-wide invariants.
//!
//! # Architecture
//!
//! The module is organised into two layers:
//!
//! - [`core`](self::core): the internal submodule where each type is defined
//! in its own file. This keeps compilation units small and dependencies
//! explicit.
//! - Re-exports: `pub use core::*` lifts every type to the `types`
//! namespace, so consumers can write `use libvctrl_handler::types::Blob`
//! instead of the longer `libvctrl_handler::types::core::blob::Blob`.
//!
//! ## Why a `core` submodule?
//!
//! Grouping type definitions in `core` provides a clean separation between
//! the internal module layout and the public API. The public path remains
//! stable even if the internal file organisation changes. This mirrors the
//! pattern used by the [`traits`](crate::traits) module.
//!
//! ## Validation helpers
//!
//! Two validation functions are provided:
//!
//! - [`validate_name`]: checks general-purpose names (branches, tags, etc.)
//! for non-emptiness and maximum length.
//! - [`validate_tree_entry_name`]: extends [`validate_name`] with extra
//! checks for tree entry names to prevent path traversal and reserved
//! names.
//!
//! Both are `pub(crate)` because name validation is an internal invariant.
//! External users should never be able to inject a name that bypasses these
//! checks; constructors like [`Tag::new`](crate::Tag::new) and
//! [`TreeEntry::new`](crate::TreeEntry::new) call them automatically.
//!
//! # Design Rationale
//!
//! - **Immutability by default**: All types in `core` have private fields
//! and public constructors. Once created, they cannot be mutated. This
//! reflects the content-addressable storage philosophy: an object's hash
//! is derived from its bytes, so mutating the object would change its
//! identity.
//! - **Validation at construction**: Constructors return `Result` to force
//! callers to handle invalid input immediately. This prevents malformed
//! objects from entering the system.
//! - **Re-export ergonomics**: Lifting all types to the parent module
//! simplifies imports without sacrificing internal organisation.
//!
//! # Crate name assumption
//!
//! For documentation doctests this module assumes the library crate is named
//! `libvctrl_handler`. Adjust import paths accordingly when integrating into
//! a real project.
//!
//! # Examples
//!
//! Using a re-exported type:
//!
//! ```
//! use libvctrl_handler::types::Blob;
//!
//! let blob = Blob::new(b"hello world".to_vec());
//! assert_eq!(blob.size(), 11);
//! ```
/// Core object-model types.
///
/// # Purpose
///
/// This submodule defines the fundamental building blocks of the version
/// control system: [`Blob`], [`Tree`], [`Commit`], [`Tag`], [`Hash`], and
/// supporting types like [`UserID`], [`CommitMeta`], and [`TreeEntry`].
/// Each type is designed as a plain-old-data struct with immutable fields,
/// mirroring the content-addressable storage philosophy.
///
/// # Design Rationale
///
/// Each type is placed in its own file for maintainability and to reduce
/// merge conflicts. The types are intentionally public so that external
/// consumers can construct and inspect them, while mutations remain the
/// responsibility of higher-level managers. The fields remain private to
/// preserve invariants established during construction.
///
/// # How It Fits
///
/// The `core` module is the source of truth. Other subsystems (`traits`,
/// `handlers`, encoders, decoders) depend on these types through re-exports
/// from the parent `types` module, keeping dependency graphs shallow and
/// avoiding circular imports.
///
/// # Examples
///
/// Constructing a blob through the `core` path:
///
/// ```
/// use libvctrl_handler::types::core::Blob;
///
/// let blob = Blob::new(b"example data".to_vec());
/// assert_eq!(blob.data(), b"example data");
/// ```
use crateMAX_NAME_LENGTH;
use crateVctrlError;
/// Re-exports all types from `core` into the `types` namespace.
///
/// # Purpose
///
/// Without this re-export, consumers would need to write
/// `use libvctrl_handler::types::core::Blob;`. By lifting them to `types`,
/// we present a cleaner public API while keeping the implementation modular.
///
/// # Design Rationale
///
/// This re-export is an ergonomic convenience. It does not duplicate the
/// types; it merely exposes them at a shallower path. This is a common Rust
/// pattern for modules that contain many public items.
///
/// # Examples
///
/// ```
/// use libvctrl_handler::types::Blob;
///
/// let blob = Blob::new(b"lifted access".to_vec());
/// assert_eq!(blob.size(), 13);
/// ```
pub use *;
/// Validates a general-purpose name (branch, tag, remote, etc.) against
/// length constraints.
///
/// Names are required to be non-empty and not exceed
/// [`MAX_NAME_LENGTH`](crate::constants::MAX_NAME_LENGTH) bytes.
///
/// # Purpose
///
/// This function is `pub(crate)` because name validation is an internal
/// invariant; external users should never be able to inject a name that
/// bypasses these checks. Public constructors call this function before
/// accepting a name.
///
/// # How It Works
///
/// 1. Checks emptiness, returning `VctrlError::InvalidName` if empty.
/// 2. Checks length against the compile-time constant `MAX_NAME_LENGTH`.
/// 3. Returns `Ok(())` if all checks pass.
///
/// # Errors
///
/// Returns [`VctrlError::InvalidName`] with a descriptive message when the
/// name is empty or too long.
pub
/// Validates a name intended for a tree entry (file or directory name inside
/// a tree object).
///
/// # Purpose
///
/// In addition to the checks performed by [`validate_name`], this function
/// forbids:
///
/// - Slash characters (`/`), which would interfere with path parsing.
/// - The reserved names `.` and `..`, which have special meanings in
/// Unix-like systems.
///
/// # Why It Exists
///
/// Tree entries must be simple, flat names without directory separators.
/// Enforcing this at the validation layer prevents entire classes of
/// path-traversal and tree-corruption bugs before they reach storage.
///
/// # How It Works
///
/// 1. Calls [`validate_name`] to enforce basic constraints.
/// 2. Checks for `/`, `.`, and `..`.
/// 3. Returns `Ok(())` if all checks pass.
///
/// # Errors
///
/// Returns [`VctrlError::InvalidName`] if the name is empty, too long, or
/// contains forbidden characters or names.
pub