mod cache_manager;
mod crates_io;
mod git;
mod local_path;
mod workspace;
mod composite;

pub use crates_io::CratesIoFetcher;
pub use git::GitFetcher;
pub use local_path::LocalPathFetcher;
pub use workspace::WorkspaceFetcher;
pub use composite::CompositeFetcher;

use crate::models::ScanCrateError;
use async_trait::async_trait;
use std::path::PathBuf;

#[async_trait]
/// Trait for fetching crate source code.
/// This allows for different fetching strategies to be implemented and used interchangeably.
pub trait CrateFetcher: Send + Sync {
    /// Fetches the source code for a given crate name and optional version requirement.
    ///
    /// # Arguments
    /// * `name` - The name of the crate (e.g., "serde").
    /// * `version_req` - An optional version requirement string (e.g., "1.0", "^1.0.130", "=1.0.130").
    ///                   If None, the fetcher should attempt to get the latest version.
    ///
    /// # Returns
    /// A `Result` containing the `PathBuf` to the fetched crate source directory on success,
    /// or a `ScanCrateError` on failure.
    async fn fetch_crate_src(
        &self,
        name: &str,
        version_req: Option<&str>,
    ) -> Result<PathBuf, ScanCrateError>;
}