]>
Commit | Line | Data |
---|---|---|
2b46d039 | 1 | use std::collections::HashMap; |
798b620c | 2 | use std::mem; |
2b46d039 | 3 | |
c96d936b | 4 | use semver::Version; |
2b46d039 AC |
5 | use core::{Dependency, PackageId, SourceId}; |
6 | ||
7 | use 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 | 14 | pub struct Summary { |
61c95b75 | 15 | package_id: PackageId, |
2b46d039 AC |
16 | dependencies: Vec<Dependency>, |
17 | features: HashMap<String, Vec<String>>, | |
1ce76415 CL |
18 | } |
19 | ||
20 | impl 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 |
91 | impl PartialEq for Summary { |
92 | fn eq(&self, other: &Summary) -> bool { | |
93 | self.package_id == other.package_id | |
94 | } | |
95 | } | |
96 | ||
da0ec9a3 | 97 | pub trait SummaryVec { |
2f576175 | 98 | fn names(&self) -> Vec<String>; |
da0ec9a3 YK |
99 | } |
100 | ||
101 | impl 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 | } |