Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

9. Storage trait for dependency injection

Date: 2026-04-22

Status

Accepted

Context

Collectors need to read files and access git/OpenCode databases. Collectors must support testing without real filesystems.

Decision

Cerebro defines traits for dependency injection:

#![allow(unused)]
fn main() {
pub trait Storage: Send + Sync {
    async fn exists(&self, path: &Path) -> bool;
    async fn read_to_string(&self, path: &Path) -> Result<String>;
    // ...
}

pub trait Git: Send + Sync {
    async fn commits(&self, repo_path: &Path) -> Result<Vec<GitCommit>>;
    async fn modified_files(&self, repo_path: &Path) -> Result<Vec<FileChange>>;
}
}

Implementations:

  • TokioStorage: Uses tokio for async file I/O
  • Git2: Uses git2 crate for git operations, with commits limited to 20 per project
  • SqlxDb: Uses sqlx for OpenCode SQLite queries

Consequences

Pros

  • Testable without real filesystem
  • Swap implementations, such as mock storage for tests
  • Clear abstraction boundaries

Cons

  • Trait indirection overhead
  • More complex DI setup

Notes

See cerebro-core/src/storage.rs.