]> git.proxmox.com Git - cargo.git/blame - src/cargo/core/summary.rs
Auto merge of #2159 - Manishearth:native-diag, r=alexcrichton
[cargo.git] / src / cargo / core / summary.rs
CommitLineData
2b46d039 1use std::collections::HashMap;
798b620c 2use std::mem;
2b46d039 3
c96d936b 4use semver::Version;
2b46d039
AC
5use core::{Dependency, PackageId, SourceId};
6
7use util::{CargoResult, human};
1ce76415 8
798b620c
AC
9/// Subset of a `Manifest`. Contains only the most important informations about
10/// a package.
c7641c24 11///
64ff29ff 12/// Summaries are cloned, and should not be mutated after creation
213afc02 13#[derive(Debug,Clone)]
1ce76415 14pub struct Summary {
61c95b75 15 package_id: PackageId,
2b46d039
AC
16 dependencies: Vec<Dependency>,
17 features: HashMap<String, Vec<String>>,
1ce76415
CL
18}
19
20impl Summary {
2b46d039
AC
21 pub fn new(pkg_id: PackageId,
22 dependencies: Vec<Dependency>,
23 features: HashMap<String, Vec<String>>) -> CargoResult<Summary> {
24 for dep in dependencies.iter() {
7a2facba 25 if features.get(dep.name()).is_some() {
2b46d039 26 return Err(human(format!("Features and dependencies cannot have \
7a2facba 27 the same name: `{}`", dep.name())))
2b46d039
AC
28 }
29 if dep.is_optional() && !dep.is_transitive() {
30 return Err(human(format!("Dev-dependencies are not allowed \
31 to be optional: `{}`",
7a2facba 32 dep.name())))
2b46d039
AC
33 }
34 }
35 for (feature, list) in features.iter() {
36 for dep in list.iter() {
80fe0e6d 37 let mut parts = dep.splitn(2, '/');
f5f34e85
AC
38 let dep = parts.next().unwrap();
39 let is_reexport = parts.next().is_some();
df9cf066 40 if !is_reexport && features.get(dep).is_some() { continue }
7a2facba 41 match dependencies.iter().find(|d| d.name() == dep) {
2b46d039 42 Some(d) => {
f5f34e85 43 if d.is_optional() || is_reexport { continue }
2b46d039
AC
44 return Err(human(format!("Feature `{}` depends on `{}` \
45 which is not an optional \
46 dependency.\nConsider adding \
47 `optional = true` to the \
48 dependency", feature, dep)))
49 }
f5f34e85
AC
50 None if is_reexport => {
51 return Err(human(format!("Feature `{}` requires `{}` \
52 which is not an optional \
53 dependency", feature, dep)))
54 }
2b46d039
AC
55 None => {
56 return Err(human(format!("Feature `{}` includes `{}` \
57 which is neither a dependency \
58 nor another feature",
59 feature, dep)))
60 }
61 }
62 }
1ce76415 63 }
2b46d039
AC
64 Ok(Summary {
65 package_id: pkg_id,
66 dependencies: dependencies,
67 features: features,
68 })
1ce76415
CL
69 }
70
7a2facba
AC
71 pub fn package_id(&self) -> &PackageId { &self.package_id }
72 pub fn name(&self) -> &str { self.package_id().name() }
73 pub fn version(&self) -> &Version { self.package_id().version() }
74 pub fn source_id(&self) -> &SourceId { self.package_id.source_id() }
75 pub fn dependencies(&self) -> &[Dependency] { &self.dependencies }
76 pub fn features(&self) -> &HashMap<String, Vec<String>> { &self.features }
798b620c 77
816373d9
AC
78 pub fn override_id(mut self, id: PackageId) -> Summary {
79 self.package_id = id;
80 self
81 }
82
157d639a
AC
83 pub fn map_dependencies<F>(mut self, f: F) -> Summary
84 where F: FnMut(Dependency) -> Dependency {
798b620c
AC
85 let deps = mem::replace(&mut self.dependencies, Vec::new());
86 self.dependencies = deps.into_iter().map(f).collect();
87 self
88 }
1ce76415 89}
da0ec9a3 90
58518273
AC
91impl PartialEq for Summary {
92 fn eq(&self, other: &Summary) -> bool {
93 self.package_id == other.package_id
94 }
95}
96
da0ec9a3 97pub trait SummaryVec {
2f576175 98 fn names(&self) -> Vec<String>;
da0ec9a3
YK
99}
100
101impl SummaryVec for Vec<Summary> {
2f576175
YK
102 // TODO: Move to Registry
103 fn names(&self) -> Vec<String> {
7a2facba 104 self.iter().map(|summary| summary.name().to_string()).collect()
da0ec9a3
YK
105 }
106
da0ec9a3 107}