Skip to main content

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}