cuenv_vcs/hasher.rs
1//! The [`VcsHasher`] trait.
2
3use crate::error::Result;
4use async_trait::async_trait;
5use serde::{Deserialize, Serialize};
6use std::path::PathBuf;
7
8/// A single input file resolved and hashed by a [`VcsHasher`].
9#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
10pub struct HashedInput {
11 /// Path relative to the workspace root, with forward slashes.
12 pub relative_path: PathBuf,
13 /// Absolute path on disk (canonicalized when possible).
14 pub absolute_path: PathBuf,
15 /// Lowercase hex SHA-256 of the file content.
16 pub sha256: String,
17 /// File size in bytes.
18 pub size: u64,
19 /// Whether the file is executable when materialized.
20 pub is_executable: bool,
21}
22
23/// A pluggable strategy for resolving glob patterns and hashing the matched
24/// files.
25///
26/// The baseline implementation is [`walker::WalkHasher`](crate::walker::WalkHasher),
27/// which walks the filesystem and streams SHA-256 over each matched file.
28/// Future implementations can use a VCS (e.g. git index lookups) to skip
29/// re-hashing files whose content hasn't changed.
30#[async_trait]
31pub trait VcsHasher: Send + Sync {
32 /// Resolve `patterns` (globs, directories, or explicit file paths) and
33 /// return a [`HashedInput`] for every matched file.
34 ///
35 /// Results are deduplicated and returned in deterministic order so the
36 /// same inputs always produce the same sequence.
37 ///
38 /// # Errors
39 ///
40 /// Returns an error if a pattern is invalid or if any filesystem
41 /// operation fails.
42 async fn resolve_and_hash(&self, patterns: &[String]) -> Result<Vec<HashedInput>>;
43
44 /// Short, stable identifier for this implementation (e.g. `"walk"`,
45 /// `"git"`). Useful for diagnostics and metrics.
46 fn name(&self) -> &'static str;
47}