Skip to main content

cup_cli/config/
dependency.rs

1use std::path::{Path, PathBuf};
2
3use anyhow::anyhow;
4use path_clean::PathClean;
5
6use crate::{config::Shelling, utils::CupData};
7
8#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
9pub struct DependencyConfig {
10    pub path: Option<String>,
11    pub git: Option<String>,
12    pub features: Option<Vec<String>>,
13    #[serde(rename = "default-features")]
14    pub defaut_features: Option<bool>,
15    pub optional: Option<bool>,
16}
17
18impl<P: AsRef<Path>> Shelling<anyhow::Result<Dependency>, P> for DependencyConfig {
19    fn shelling(self, base: P) -> anyhow::Result<Dependency> {
20        let src = if let Some(path) = self.path {
21            let path = PathBuf::from(path);
22            let path = if path.is_absolute() {
23                path
24            } else {
25                base.as_ref().join(path)
26            };
27            DependencySource::Local(path.clean())
28        } else if let Some(git) = self.git {
29            let mut parts = git.split('/').into_iter().collect::<Vec<_>>();
30            if parts.len() != 3 {
31                return Err(anyhow!(
32                    "Invalid git mark format, should be owner/repo/tag."
33                ));
34            }
35            let owner = parts.remove(0);
36            let repo = parts.remove(0);
37            let tag = parts.remove(0);
38            DependencySource::Git {
39                owner: owner.to_string(),
40                repo: repo.to_string(),
41                tag: tag.to_string(),
42            }
43        } else {
44            return Err(anyhow!(
45                "Invalid dependency config, must specify either git or path."
46            ));
47        };
48        Ok(Dependency {
49            src,
50            features: self.features.unwrap_or_default(),
51            defaut_features: self.defaut_features.unwrap_or(true),
52            optional: self.optional.unwrap_or(false),
53        })
54    }
55}
56
57#[derive(Debug, Clone)]
58pub enum DependencySource {
59    Local(PathBuf),
60    Git {
61        owner: String,
62        repo: String,
63        tag: String,
64    },
65}
66
67impl DependencySource {
68    /// 获取依赖项所对应的本地路径
69    pub fn local_path(&self) -> PathBuf {
70        match self {
71            Self::Local(path) => path.clone(),
72            Self::Git { owner, repo, tag } => CupData::git(owner, repo, tag),
73        }
74    }
75}
76
77#[derive(Debug, Clone)]
78pub struct Dependency {
79    pub src: DependencySource,
80    pub features: Vec<String>,
81    pub defaut_features: bool,
82    pub optional: bool,
83}