]> git.proxmox.com Git - rustc.git/blob - src/tools/cargo/src/cargo/ops/cargo_add/crate_spec.rs
New upstream version 1.70.0+dfsg2
[rustc.git] / src / tools / cargo / src / cargo / ops / cargo_add / crate_spec.rs
1 //! Crate name parsing.
2
3 use anyhow::Context as _;
4
5 use super::Dependency;
6 use crate::util::toml_mut::dependency::RegistrySource;
7 use crate::util::validate_package_name;
8 use crate::CargoResult;
9
10 /// User-specified crate
11 ///
12 /// This can be a
13 /// - Name (e.g. `docopt`)
14 /// - Name and a version req (e.g. `docopt@^0.8`)
15 /// - Path
16 #[derive(Debug)]
17 pub struct CrateSpec {
18 /// Crate name
19 name: String,
20 /// Optional version requirement
21 version_req: Option<String>,
22 }
23
24 impl CrateSpec {
25 /// Convert a string to a `Crate`
26 pub fn resolve(pkg_id: &str) -> CargoResult<Self> {
27 let (name, version) = pkg_id
28 .split_once('@')
29 .map(|(n, v)| (n, Some(v)))
30 .unwrap_or((pkg_id, None));
31
32 validate_package_name(name, "dependency name", "")?;
33
34 if let Some(version) = version {
35 semver::VersionReq::parse(version)
36 .with_context(|| format!("invalid version requirement `{version}`"))?;
37 }
38
39 let id = Self {
40 name: name.to_owned(),
41 version_req: version.map(|s| s.to_owned()),
42 };
43
44 Ok(id)
45 }
46
47 /// Generate a dependency entry for this crate specifier
48 pub fn to_dependency(&self) -> CargoResult<Dependency> {
49 let mut dep = Dependency::new(self.name());
50 if let Some(version_req) = self.version_req() {
51 dep = dep.set_source(RegistrySource::new(version_req));
52 }
53 Ok(dep)
54 }
55
56 pub fn name(&self) -> &str {
57 &self.name
58 }
59
60 pub fn version_req(&self) -> Option<&str> {
61 self.version_req.as_deref()
62 }
63 }