git_commitgraph/graph/
access.rs1use crate::{
2 file::{self, Commit, File},
3 graph::{self, Graph},
4};
5
6impl Graph {
8 pub fn commit_at(&self, pos: graph::Position) -> Commit<'_> {
13 let r = self.lookup_by_pos(pos);
14 r.file.commit_at(r.pos)
15 }
16
17 pub fn commit_by_id(&self, id: impl AsRef<git_hash::oid>) -> Option<Commit<'_>> {
19 let r = self.lookup_by_id(id.as_ref())?;
20 Some(r.file.commit_at(r.file_pos))
21 }
22
23 pub fn id_at(&self, pos: graph::Position) -> &git_hash::oid {
28 let r = self.lookup_by_pos(pos);
29 r.file.id_at(r.pos)
30 }
31
32 pub fn iter_commits(&self) -> impl Iterator<Item = Commit<'_>> {
34 self.files.iter().flat_map(|file| file.iter_commits())
35 }
36
37 pub fn iter_ids(&self) -> impl Iterator<Item = &git_hash::oid> {
39 self.files.iter().flat_map(|file| file.iter_ids())
40 }
41
42 pub fn lookup(&self, id: impl AsRef<git_hash::oid>) -> Option<graph::Position> {
44 Some(self.lookup_by_id(id.as_ref())?.graph_pos)
45 }
46
47 pub fn num_commits(&self) -> u32 {
49 self.files.iter().map(|f| f.num_commits()).sum()
50 }
51}
52
53impl Graph {
55 fn lookup_by_id(&self, id: &git_hash::oid) -> Option<LookupByIdResult<'_>> {
56 let mut current_file_start = 0;
57 for file in &self.files {
58 if let Some(lex_pos) = file.lookup(id) {
59 return Some(LookupByIdResult {
60 file,
61 file_pos: lex_pos,
62 graph_pos: graph::Position(current_file_start + lex_pos.0),
63 });
64 }
65 current_file_start += file.num_commits();
66 }
67 None
68 }
69
70 fn lookup_by_pos(&self, pos: graph::Position) -> LookupByPositionResult<'_> {
71 let mut remaining = pos.0;
72 for (file_index, file) in self.files.iter().enumerate() {
73 match remaining.checked_sub(file.num_commits()) {
74 Some(v) => remaining = v,
75 None => {
76 return LookupByPositionResult {
77 file,
78 _file_index: file_index,
79 pos: file::Position(remaining),
80 }
81 }
82 }
83 }
84 panic!("graph position too large: {}", pos.0);
85 }
86}
87
88#[derive(Clone)]
89struct LookupByIdResult<'a> {
90 pub file: &'a File,
91 pub graph_pos: graph::Position,
92 pub file_pos: file::Position,
93}
94
95#[derive(Clone)]
96struct LookupByPositionResult<'a> {
97 pub file: &'a File,
98 pub _file_index: usize,
99 pub pos: file::Position,
100}