Skip to main content

auths_infra_git/
ref_store.rs

1use auths_core::ports::storage::{RefReader, RefWriter, StorageError};
2
3use crate::error::map_git2_error;
4use crate::helpers;
5use crate::repo::GitRepo;
6
7/// Git-backed implementation of `RefReader` and `RefWriter`.
8///
9/// References are Git refs. `resolve_ref` returns the commit OID bytes
10/// the ref points to. `update_ref` creates or updates a ref to point
11/// at a commit whose tree contains the given data.
12///
13/// Usage:
14/// ```ignore
15/// use auths_infra_git::{GitRepo, GitRefStore};
16/// use auths_core::ports::storage::RefReader;
17///
18/// let repo = GitRepo::open("/path/to/repo")?;
19/// let store = GitRefStore::new(&repo);
20/// let oid_bytes = store.resolve_ref("refs/auths/registry")?;
21/// ```
22pub struct GitRefStore<'r> {
23    repo: &'r GitRepo,
24}
25
26impl<'r> GitRefStore<'r> {
27    pub fn new(repo: &'r GitRepo) -> Self {
28        Self { repo }
29    }
30}
31
32impl RefReader for GitRefStore<'_> {
33    fn resolve_ref(&self, refname: &str) -> Result<Vec<u8>, StorageError> {
34        self.repo.with_repo(|repo| {
35            let oid = helpers::resolve_git_ref(repo, refname).map_err(map_git2_error)?;
36            Ok(oid.as_bytes().to_vec())
37        })
38    }
39
40    fn list_refs(&self, glob: &str) -> Result<Vec<String>, StorageError> {
41        self.repo
42            .with_repo(|repo| helpers::list_refs_matching(repo, glob).map_err(map_git2_error))
43    }
44}
45
46impl RefWriter for GitRefStore<'_> {
47    fn update_ref(&self, refname: &str, target: &[u8], message: &str) -> Result<(), StorageError> {
48        self.repo.with_repo(|repo| {
49            helpers::create_ref_commit(repo, refname, target, "data", message)
50                .map_err(map_git2_error)?;
51            Ok(())
52        })
53    }
54
55    fn delete_ref(&self, refname: &str) -> Result<(), StorageError> {
56        self.repo
57            .with_repo(|repo| match repo.find_reference(refname) {
58                Ok(mut r) => {
59                    r.delete().map_err(map_git2_error)?;
60                    Ok(())
61                }
62                Err(e) if e.code() == git2::ErrorCode::NotFound => Ok(()),
63                Err(e) => Err(map_git2_error(e)),
64            })
65    }
66}