assemble_core/dependencies/
unresolved_dependency.rs

1use crate::dependencies::{DependencyType, Registry, ResolvedDependency};
2use crate::project::buildable::GetBuildable;
3
4use std::fmt::{Debug, Display, Formatter};
5use std::io::Write;
6use std::path::Path;
7
8/// An unresolved dependency. A dependency must be able to define what type dependency is and how
9/// to download said repository.
10pub trait Dependency: GetBuildable + Debug {
11    /// A way of identifying dependencies
12    fn id(&self) -> String;
13    /// The type of the dependency
14    fn dep_type(&self) -> DependencyType;
15    /// Try to resolve a dependency in a registry. The `cache_path` is somewhere to write files into
16    /// if necessary.
17    fn try_resolve(
18        &self,
19        registry: &dyn Registry,
20        cache_path: &Path,
21    ) -> Result<ResolvedDependency, AcquisitionError>;
22}
23
24assert_obj_safe!(Dependency);
25//
26// impl Debug for Box<dyn Dependency + Send + Sync> {
27//     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
28//         write!(f, "{:?}", self.id())
29//     }
30// }
31
32impl Display for Box<dyn Dependency + Send + Sync> {
33    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
34        write!(f, "{}", self.id())
35    }
36}
37
38/// Provide a way of turning something of one type into a type that implements [`Dependency`](Dependency)
39pub trait IntoDependency {
40    type IntoDep: Dependency;
41
42    /// Turn this type into a dependency
43    fn into_dependency(self) -> Self::IntoDep;
44}
45
46impl<D: Dependency> IntoDependency for D {
47    type IntoDep = D;
48
49    fn into_dependency(self) -> Self::IntoDep {
50        self
51    }
52}
53
54/// An error occurred while trying to download a dependency
55#[derive(Debug, thiserror::Error)]
56pub enum AcquisitionError {
57    #[error("{}", error)]
58    Custom { error: String },
59    #[error("Can't acquire dependency because url is in wrong scheme (expected = {expected}, found = {found})")]
60    IncorrectUrlScheme { found: String, expected: String },
61    #[error("File is missing")]
62    MissingFile,
63    #[error("Errors: {}", inner.iter().map(|e| e.to_string()).collect::<Vec<_>>().join(","))]
64    InnerErrors { inner: Vec<AcquisitionError> },
65}
66
67impl AcquisitionError {
68    /// Create a custom acquisition error
69    pub fn custom(message: impl ToString) -> Self {
70        Self::Custom {
71            error: message.to_string(),
72        }
73    }
74}
75
76impl FromIterator<AcquisitionError> for AcquisitionError {
77    fn from_iter<T: IntoIterator<Item = AcquisitionError>>(iter: T) -> Self {
78        Self::InnerErrors {
79            inner: iter.into_iter().collect(),
80        }
81    }
82}