repository.rs

 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 reload_index(&self);
14
15    fn load_index_text(&self, relative_file_path: &Path) -> Option<String>;
16}
17
18#[async_trait::async_trait]
19impl GitRepository for LibGitRepository {
20    fn reload_index(&self) {
21        if let Ok(mut index) = self.index() {
22            _ = index.read(false);
23        }
24    }
25
26    fn load_index_text(&self, relative_file_path: &Path) -> Option<String> {
27        fn logic(repo: &LibGitRepository, relative_file_path: &Path) -> Result<Option<String>> {
28            const STAGE_NORMAL: i32 = 0;
29            let index = repo.index()?;
30            let oid = match index.get_path(relative_file_path, STAGE_NORMAL) {
31                Some(entry) => entry.id,
32                None => return Ok(None),
33            };
34
35            let content = repo.find_blob(oid)?.content().to_owned();
36            Ok(Some(String::from_utf8(content)?))
37        }
38
39        match logic(&self, relative_file_path) {
40            Ok(value) => return value,
41            Err(err) => log::error!("Error loading head text: {:?}", err),
42        }
43        None
44    }
45}
46
47#[derive(Debug, Clone, Default)]
48pub struct FakeGitRepository {
49    state: Arc<Mutex<FakeGitRepositoryState>>,
50}
51
52#[derive(Debug, Clone, Default)]
53pub struct FakeGitRepositoryState {
54    pub index_contents: HashMap<PathBuf, String>,
55}
56
57impl FakeGitRepository {
58    pub fn open(state: Arc<Mutex<FakeGitRepositoryState>>) -> Arc<Mutex<dyn GitRepository>> {
59        Arc::new(Mutex::new(FakeGitRepository { state }))
60    }
61}
62
63#[async_trait::async_trait]
64impl GitRepository for FakeGitRepository {
65    fn reload_index(&self) {}
66
67    fn load_index_text(&self, path: &Path) -> Option<String> {
68        let state = self.state.lock();
69        state.index_contents.get(path).cloned()
70    }
71}