1use anyhow::Result;
2use collections::HashMap;
3use parking_lot::Mutex;
4use std::{
5 path::{Path, PathBuf},
6 sync::Arc,
7};
8
9pub use git2::Repository as LibGitRepository;
10
11#[async_trait::async_trait]
12pub trait GitRepository: Send {
13 fn load_index(&self, relative_file_path: &Path) -> Option<String>;
14}
15
16#[async_trait::async_trait]
17impl GitRepository for LibGitRepository {
18 fn load_index(&self, relative_file_path: &Path) -> Option<String> {
19 fn logic(repo: &LibGitRepository, relative_file_path: &Path) -> Result<Option<String>> {
20 const STAGE_NORMAL: i32 = 0;
21 let index = repo.index()?;
22 let oid = match index.get_path(relative_file_path, STAGE_NORMAL) {
23 Some(entry) => entry.id,
24 None => return Ok(None),
25 };
26
27 let content = repo.find_blob(oid)?.content().to_owned();
28 Ok(Some(String::from_utf8(content)?))
29 }
30
31 match logic(&self, relative_file_path) {
32 Ok(value) => return value,
33 Err(err) => log::error!("Error loading head text: {:?}", err),
34 }
35 None
36 }
37}
38
39#[derive(Debug, Clone, Default)]
40pub struct FakeGitRepository {
41 state: Arc<Mutex<FakeGitRepositoryState>>,
42}
43
44#[derive(Debug, Clone, Default)]
45pub struct FakeGitRepositoryState {
46 pub index_contents: HashMap<PathBuf, String>,
47}
48
49impl FakeGitRepository {
50 pub fn open(state: Arc<Mutex<FakeGitRepositoryState>>) -> Arc<Mutex<dyn GitRepository>> {
51 Arc::new(Mutex::new(FakeGitRepository { state }))
52 }
53}
54
55#[async_trait::async_trait]
56impl GitRepository for FakeGitRepository {
57 fn load_index(&self, path: &Path) -> Option<String> {
58 let state = self.state.lock();
59 state.index_contents.get(path).cloned()
60 }
61}