Skip to main content

symposium_ferris/crate_sources/
mod.rs

1//! Rust-specific crate source functionality
2
3use std::path::PathBuf;
4
5use crate::Result;
6
7mod cache;
8mod extraction;
9pub(crate) mod mcp;
10mod version;
11
12pub use cache::CacheManager;
13pub use extraction::CrateExtractor;
14pub use version::VersionResolver;
15
16/// Result of fetching a crate's sources
17#[derive(Debug, Clone)]
18pub struct FetchResult {
19    /// The exact version that was fetched
20    pub version: String,
21    /// Path to the extracted crate sources on disk
22    pub path: PathBuf,
23}
24
25/// Builder for accessing Rust crate source code
26pub struct RustCrateFetch {
27    crate_name: String,
28    version_spec: Option<String>,
29    cwd: PathBuf,
30}
31
32impl RustCrateFetch {
33    /// Create a new fetch request for the given crate name
34    pub fn new(name: &str, cwd: impl Into<PathBuf>) -> Self {
35        Self {
36            crate_name: name.to_string(),
37            version_spec: None,
38            cwd: cwd.into(),
39        }
40    }
41
42    /// Specify a version constraint (e.g., "^1.0", "=1.2.3")
43    pub fn version(mut self, version: &str) -> Self {
44        self.version_spec = Some(version.to_string());
45        self
46    }
47
48    /// Fetch the crate sources, returning the path to extracted sources
49    pub async fn fetch(self) -> Result<FetchResult> {
50        // 1. Resolve version
51        let resolver = VersionResolver::new(self.cwd);
52        let version = resolver
53            .resolve_version(&self.crate_name, self.version_spec.as_deref())
54            .await?;
55
56        // 2. Get or extract crate source
57        let cache_manager = CacheManager::new()?;
58        let extractor = CrateExtractor::new();
59
60        let path = cache_manager
61            .get_or_extract_crate(&self.crate_name, &version, &extractor)
62            .await?;
63
64        Ok(FetchResult { version, path })
65    }
66}