assemble_core/dependencies/
file_dependency.rs

1use crate::dependencies::{
2    AcquisitionError, Dependency, DependencyType, Registry, ResolvedDependency,
3    ResolvedDependencyBuilder,
4};
5use crate::file_collection::{FileCollection, FileSet};
6use crate::project::buildable::{BuildableObject, GetBuildable};
7
8use itertools::Itertools;
9use once_cell::sync::Lazy;
10use std::collections::VecDeque;
11
12use std::path::{Path, PathBuf};
13use url::Url;
14
15#[derive(Debug)]
16pub struct FileSystem(PathBuf);
17
18#[cfg(windows)]
19impl Default for FileSystem {
20    fn default() -> Self {
21        FileSystem(PathBuf::from(r"c:\"))
22    }
23}
24
25#[cfg(unix)]
26impl Default for FileSystem {
27    fn default() -> Self {
28        FileSystem(PathBuf::from(r"/"))
29    }
30}
31
32impl Registry for FileSystem {
33    fn url(&self) -> Url {
34        Url::from_directory_path(self.0.clone())
35            .unwrap_or_else(|_| panic!("couldn't treat {:?} as root directory for URL", self.0))
36    }
37
38    fn supported(&self) -> Vec<DependencyType> {
39        vec![FILE_SYSTEM_TYPE.clone()]
40    }
41}
42
43/// The file system dependency type. Just represents a normal
44pub static FILE_SYSTEM_TYPE: Lazy<DependencyType> =
45    Lazy::new(|| DependencyType::new("file", "direct_file_url", ["*"]));
46
47impl GetBuildable for PathBuf {
48    fn as_buildable(&self) -> BuildableObject {
49        BuildableObject::None
50    }
51}
52
53impl Dependency for PathBuf {
54    fn id(&self) -> String {
55        format!("{:?}", self)
56    }
57
58    fn dep_type(&self) -> DependencyType {
59        FILE_SYSTEM_TYPE.clone()
60    }
61
62    fn try_resolve(
63        &self,
64        registry: &dyn Registry,
65        _cache_path: &Path,
66    ) -> Result<ResolvedDependency, AcquisitionError> {
67        let url = registry.url();
68        if url.scheme() != "file" {
69            return Err(AcquisitionError::IncorrectUrlScheme {
70                found: url.scheme().to_string(),
71                expected: "file".to_string(),
72            });
73        }
74        println!("registry url = {}", url);
75        let file_system_url = url
76            .to_file_path()
77            .unwrap_or_else(|_| panic!("couldn't treat {} as a path", url));
78        if self.is_absolute() {
79            Ok(ResolvedDependencyBuilder::new(self.clone()).finish())
80        } else {
81            let path = file_system_url.join(self);
82            Ok(ResolvedDependencyBuilder::new(path).finish())
83        }
84    }
85}
86
87impl Dependency for FileSet {
88    fn id(&self) -> String {
89        format!("{:?}", self.path().unwrap())
90    }
91
92    fn dep_type(&self) -> DependencyType {
93        FILE_SYSTEM_TYPE.clone()
94    }
95
96    fn try_resolve(
97        &self,
98        registry: &dyn Registry,
99        cache_path: &Path,
100    ) -> Result<ResolvedDependency, AcquisitionError> {
101        let mut paths = self.files().into_iter().collect::<VecDeque<_>>();
102        let first = paths.pop_front().ok_or(AcquisitionError::MissingFile)?;
103        let output = first.try_resolve(registry, Path::new(""))?;
104        paths
105            .into_iter()
106            .map(|path| path.try_resolve(registry, cache_path))
107            .fold(
108                Ok(output),
109                |accum, next| -> Result<ResolvedDependency, AcquisitionError> {
110                    let accum = accum?;
111                    let next = next?;
112                    Ok(accum.join(next))
113                },
114            )
115    }
116}