radicle: Return individual results for repo in `repositories_by_id`

Change `repositories_by_id` to return `impl Iterator<Item = Result<RepositoryInfo,
RepositoryError>>`
instead of `Result<Vec<RepositoryInfo>, RepositoryError>`.
This allows callers to handle failures on a per-repository basis rather
than having the
entire operation fail if a single repository lookup fails.

Previously, the method would stop processing and return an error as soon
as any repository failed to load. Now it processes all repositories and
returns individual results, making the API more resilient and giving
callers
more control over error handling.
This commit is contained in:
Sebastian Martinez 2025-11-06 09:52:14 +01:00
parent c268e809e9
commit 6d0c571ea9
2 changed files with 15 additions and 8 deletions

View File

@ -18,6 +18,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- `radicle::storage::git::Storage::repositories_by_id` returns
`impl Iterator<Item = Result<RepositoryInfo, RepositoryError>>` instead of
`Result<Vec<RepositoryInfo>, RepositoryError>`. Allowing callers to handle
failures on a per-repository basis rather than having the entire operation
fail if a single repository lookup fails.
- Re-exports from `git2` at `radicle::git::raw` were limited, using
the heartwood workspace as a filter. Dependents that require members that
are not exported anymore will have to depend on `git2` directly.

View File

@ -236,11 +236,14 @@ impl Storage {
self.path.as_path()
}
pub fn repositories_by_id<'a>(
pub fn repositories_by_id<'a, I>(
&self,
mut rids: impl Iterator<Item = &'a RepoId>,
) -> Result<Vec<RepositoryInfo>, RepositoryError> {
rids.try_fold(Vec::new(), |mut infos, rid| {
rids: I,
) -> impl Iterator<Item = Result<RepositoryInfo, RepositoryError>> + use<'_, 'a, I>
where
I: Iterator<Item = &'a RepoId>,
{
rids.map(|rid| {
let repo = self.repository(*rid)?;
let (_, head) = repo.head()?;
let refs = refs::SignedRefsAt::load(self.info.key, &repo)?;
@ -248,15 +251,14 @@ impl Storage {
.as_ref()
.map(|r| SyncedAt::new(r.at, &repo))
.transpose()?;
let info = RepositoryInfo {
Ok(RepositoryInfo {
rid: *rid,
head,
doc: repo.identity_doc()?.into(),
refs,
synced_at,
};
infos.push(info);
Ok(infos)
})
})
}