Skip to main content

uxn_tal/fetch/
local_file.rs

1use crate::fetch::provider::{FetchResult, Provider, RepoRef};
2use std::path::{Path, PathBuf};
3
4pub struct LocalFile;
5
6impl Provider for LocalFile {
7    fn parse_url(&self, url: &str) -> Option<RepoRef> {
8        if !url.starts_with("file://") {
9            return None;
10        }
11
12        // Remove "file://" prefix and get the local path
13        let path = &url[7..]; // Remove "file://"
14
15        // For local files, we create a pseudo RepoRef structure
16        Some(RepoRef {
17            host: "localhost".to_string(),
18            owner: "local".to_string(),
19            repo: "files".to_string(),
20            branch: "main".to_string(),
21            path: Some(path.to_string()),
22        })
23    }
24
25    fn fetch_tal_tree(
26        &self,
27        rf: &RepoRef,
28        out_root: &Path,
29    ) -> Result<FetchResult, Box<dyn std::error::Error>> {
30        let file_path = rf.path.as_ref().ok_or("No file path provided")?;
31
32        // Convert relative path to absolute if needed
33        let absolute_path = if Path::new(file_path).is_absolute() {
34            PathBuf::from(file_path)
35        } else {
36            // Resolve relative to current working directory
37            std::env::current_dir()?.join(file_path)
38        };
39
40        // Check if file exists
41        if !absolute_path.exists() {
42            return Err(format!("File not found: {}", absolute_path.display()).into());
43        }
44
45        // For local files, we just copy the file to the output directory
46        let file_name = absolute_path
47            .file_name()
48            .ok_or("Invalid file name")?
49            .to_string_lossy()
50            .to_string();
51
52        let target_path = out_root.join(&file_name);
53
54        // Create output directory if it doesn't exist
55        if let Some(parent) = target_path.parent() {
56            std::fs::create_dir_all(parent)?;
57        }
58
59        // Copy the file
60        std::fs::copy(&absolute_path, &target_path)?;
61
62        Ok(FetchResult {
63            entry_local: target_path.clone(),
64            all_files: vec![target_path],
65        })
66    }
67}