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
//! Logical object type enumerations for `libvctrl_handler`.
//!
//! # Purpose
//!
//! This module defines high-level, discriminative types that categorize the
//! logical kind of an object in the version control system. Rather than
//! exposing raw filesystem mode bits, it provides a semantic enum
//! ([`EntryKind`]) that distinguishes between regular files, executable
//! files, symbolic links, subdirectories, and submodule references.
//!
//! # Design Rationale
//!
//! The enum is kept separate from the low-level mode constants (like those
//! in [`crate::constants::entry_mode`]) to decouple the abstract data model
//! ("what kind of object is this?") from the serialized Unix‑style
//! representation ("what permission bits does this object have?"). This
//! allows different backends to map their own mode systems to a uniform set
//! of logical kinds, and makes the core data structures independent of
//! POSIX‑specific details.
//!
//! The module itself is deliberately small; it contains only the enum and
//! its documentation. This avoids pulling in dependencies or bloating the
//! crate with logic that belongs to higher‑level components (e.g., a decoder
//! implementation).
/// Represents the logical kind of an entry in a version control tree.
///
/// # Purpose
///
/// A [`TreeEntry`](crate::TreeEntry) must describe whether it points to
/// regular file content, an executable file, a symbolic link, a
/// subdirectory, or a submodule commit. [`EntryKind`] provides that
/// discrimination without tying the type to specific filesystem permission
/// bits.
///
/// # Design Rationale
///
/// - **`#[non_exhaustive]`**: Ensures that adding new variants in the future
/// (e.g., a hypothetical `GitAttribute` or `Custom`) will not break
/// exhaustive `match` statements in downstream code. External crates must
/// include a wildcard `_ =>` arm.
/// - **`Copy` and `Clone`**: The enum is a lightweight tag (typically 1
/// byte). Making it `Copy` allows it to be passed by value freely, which
/// is essential for a type that appears in many collection lookups and
/// comparisons.
/// - **`Hash` and `Eq`**: Enables entries to be grouped, compared, or used
/// as keys in hash maps, e.g., when indexing trees by entry kind.
/// - **Separation from mode bits**: The mapping from raw mode constants
/// (like `0o100644` or `0o120000`) to [`EntryKind`] is performed by
/// higher‑level decoder implementations. This keeps the core crate
/// independent of any particular serialization format.
///
/// # Internal Mechanism
///
/// This is a standard C‑like enum. Rust guarantees it occupies the minimum
/// required memory (a single byte on most platforms). No data is attached
/// to any variant, so the size is constant and predictable.
///
/// # Examples
///
/// Basic construction and comparison:
///
/// ```
/// use libvctrl_handler::EntryKind;
///
/// let blob = EntryKind::Blob;
/// let executable = EntryKind::Executable;
/// let symlink = EntryKind::Symlink;
/// let tree = EntryKind::Tree;
/// let submodule = EntryKind::Submodule;
///
/// // File‑like kinds are not tree‑like
/// assert_ne!(blob, tree);
/// assert_ne!(executable, tree);
/// assert_ne!(symlink, tree);
///
/// // Executable is a distinct variant from Blob
/// assert_ne!(blob, executable);
///
/// // Symlink is not the same as a regular file
/// assert_ne!(blob, symlink);
///
/// // Submodule is its own kind
/// assert_ne!(tree, submodule);
/// ```
///
/// Downstream code must use a wildcard when matching because the enum is
/// `#[non_exhaustive]`:
///
/// ```
/// use libvctrl_handler::EntryKind;
///
/// fn describe(kind: EntryKind) -> &'static str {
/// match kind {
/// EntryKind::Blob => "regular file",
/// EntryKind::Executable => "executable file",
/// EntryKind::Symlink => "symbolic link",
/// EntryKind::Tree => "directory",
/// EntryKind::Submodule => "submodule",
/// _ => "unknown", // <-- required because of #[non_exhaustive]
/// }
/// }
///
/// assert_eq!(describe(EntryKind::Blob), "regular file");
/// assert_eq!(describe(EntryKind::Submodule), "submodule");
/// ```