gitoxide_core/index/
information.rs1pub struct Options {
2 pub index: super::Options,
3 pub extension_details: bool,
5}
6
7#[cfg(feature = "serde")]
8mod serde_only {
9 use gix::index::entry::Stage;
10
11 mod ext {
12 #[derive(serde::Serialize)]
13 pub(crate) struct Tree {
14 name: String,
15 id: String,
17 num_entries: Option<u32>,
19 children: Vec<Tree>,
20 }
21
22 mod tree {
23
24 use gix::bstr::ByteSlice;
25
26 impl<'a> From<&'a gix::index::extension::Tree> for super::Tree {
27 fn from(t: &'a gix::index::extension::Tree) -> Self {
28 super::Tree {
29 name: t.name.as_bstr().to_string(),
30 id: t.id.to_hex().to_string(),
31 num_entries: t.num_entries,
32 children: t.children.iter().map(Into::into).collect(),
33 }
34 }
35 }
36
37 #[derive(serde::Serialize, serde::Deserialize)]
38 pub struct NodeId {}
39 }
40 }
41
42 #[derive(serde::Serialize)]
43 pub(crate) struct EntryKind {
44 dir: usize,
45 file: usize,
46 executable: usize,
47 symlink: usize,
48 submodule: usize,
49 other: usize,
50 }
51
52 #[derive(serde::Serialize)]
53 pub(crate) struct EntryFlag {
54 intent_to_add: usize,
55 skip_worktree: usize,
56 }
57
58 #[derive(serde::Serialize)]
59 pub struct Entries {
60 stage_0_merged: usize,
61 stage_1_base: usize,
62 stage_2_ours: usize,
63 stage_3_theirs: usize,
64 kind: EntryKind,
65 flags: EntryFlag,
66 }
67
68 #[derive(serde::Serialize)]
69 pub struct Extensions {
70 names: Vec<&'static str>,
71 tree: Option<ext::Tree>,
72 }
73
74 #[derive(serde::Serialize)]
75 pub struct Collection {
76 version: u8,
77 checksum: String,
78 entries: Entries,
79 extensions: Extensions,
80 }
81
82 impl Collection {
83 pub fn try_from_file(f: gix::index::File, extension_details: bool) -> anyhow::Result<Self> {
84 Ok(Collection {
85 version: f.version() as u8,
86 checksum: f.checksum().expect("just read from disk").to_hex().to_string(),
87 extensions: {
88 let mut names = Vec::new();
89 let tree = f.tree().and_then(|tree| {
90 names.push("tree (TREE)");
91 extension_details.then(|| tree.into())
92 });
93 if f.link().is_some() {
94 names.push("link");
95 }
96 if f.resolve_undo().is_some() {
97 names.push("resolve-undo (REUC)");
98 }
99 if f.untracked().is_some() {
100 names.push("untracked (UNTR)");
101 }
102 if f.fs_monitor().is_some() {
103 names.push("fs-monitor (FSMN)");
104 }
105 if f.had_offset_table() {
106 names.push("offset-table (IEOT)");
107 }
108 if f.had_end_of_index_marker() {
109 names.push("end-of-index (EOIE)");
110 }
111 Extensions { names, tree }
112 },
113 entries: {
114 let (mut stage_0_merged, mut stage_1_base, mut stage_2_ours, mut stage_3_theirs) = (0, 0, 0, 0);
115 let (mut dir, mut file, mut executable, mut symlink, mut submodule, mut other) = (0, 0, 0, 0, 0, 0);
116 let (mut intent_to_add, mut skip_worktree) = (0, 0);
117 for entry in f.entries() {
118 match entry.flags.stage() {
119 Stage::Unconflicted => stage_0_merged += 1,
120 Stage::Base => stage_1_base += 1,
121 Stage::Ours => stage_2_ours += 1,
122 Stage::Theirs => stage_3_theirs += 1,
123 }
124 match entry.mode {
125 gix::index::entry::Mode::DIR => dir += 1,
126 gix::index::entry::Mode::FILE => file += 1,
127 gix::index::entry::Mode::FILE_EXECUTABLE => executable += 1,
128 gix::index::entry::Mode::SYMLINK => symlink += 1,
129 gix::index::entry::Mode::COMMIT => submodule += 1,
130 _ => other += 1,
131 }
132 if entry.flags.contains(gix::index::entry::Flags::INTENT_TO_ADD) {
133 intent_to_add += 1;
134 }
135 if entry.flags.contains(gix::index::entry::Flags::SKIP_WORKTREE) {
136 skip_worktree += 1;
137 }
138 }
139 Entries {
140 stage_0_merged,
141 stage_1_base,
142 stage_2_ours,
143 stage_3_theirs,
144 kind: EntryKind {
145 dir,
146 file,
147 executable,
148 symlink,
149 submodule,
150 other,
151 },
152 flags: EntryFlag {
153 intent_to_add,
154 skip_worktree,
155 },
156 }
157 },
158 })
159 }
160 }
161}
162#[cfg(feature = "serde")]
163pub(crate) use serde_only::Collection;