|
| 1 | +use std::cell::{Ref, RefCell}; |
1 | 2 | use std::collections::HashMap;
|
2 | 3 | use std::fmt;
|
3 | 4 | use std::hash;
|
4 |
| -use std::slice; |
5 | 5 | use std::path::{Path, PathBuf};
|
| 6 | + |
6 | 7 | use semver::Version;
|
7 | 8 |
|
8 |
| -use core::{Dependency, Manifest, PackageId, SourceId, Registry, Target, Summary, Metadata}; |
| 9 | +use core::{Dependency, Manifest, PackageId, SourceId, Target}; |
| 10 | +use core::{Summary, Metadata, SourceMap}; |
9 | 11 | use ops;
|
10 |
| -use util::{CargoResult, graph, Config}; |
| 12 | +use util::{CargoResult, Config, LazyCell, ChainError, internal, human}; |
11 | 13 | use rustc_serialize::{Encoder,Encodable};
|
12 |
| -use core::source::Source; |
13 | 14 |
|
14 | 15 | /// Information about a package that is available somewhere in the file system.
|
15 | 16 | ///
|
@@ -118,78 +119,46 @@ impl hash::Hash for Package {
|
118 | 119 | }
|
119 | 120 | }
|
120 | 121 |
|
121 |
| -#[derive(PartialEq,Clone,Debug)] |
122 |
| -pub struct PackageSet { |
123 |
| - packages: Vec<Package>, |
| 122 | +pub struct PackageSet<'cfg> { |
| 123 | + packages: Vec<(PackageId, LazyCell<Package>)>, |
| 124 | + sources: RefCell<SourceMap<'cfg>>, |
124 | 125 | }
|
125 | 126 |
|
126 |
| -impl PackageSet { |
127 |
| - pub fn new(packages: &[Package]) -> PackageSet { |
128 |
| - //assert!(packages.len() > 0, |
129 |
| - // "PackageSet must be created with at least one package") |
130 |
| - PackageSet { packages: packages.to_vec() } |
131 |
| - } |
132 |
| - |
133 |
| - pub fn is_empty(&self) -> bool { |
134 |
| - self.packages.is_empty() |
135 |
| - } |
136 |
| - |
137 |
| - pub fn len(&self) -> usize { |
138 |
| - self.packages.len() |
139 |
| - } |
140 |
| - |
141 |
| - pub fn pop(&mut self) -> Package { |
142 |
| - self.packages.pop().expect("PackageSet.pop: empty set") |
143 |
| - } |
144 |
| - |
145 |
| - /// Get a package by name out of the set |
146 |
| - pub fn get(&self, name: &str) -> &Package { |
147 |
| - self.packages.iter().find(|pkg| name == pkg.name()) |
148 |
| - .expect("PackageSet.get: empty set") |
149 |
| - } |
150 |
| - |
151 |
| - pub fn get_all(&self, names: &[&str]) -> Vec<&Package> { |
152 |
| - names.iter().map(|name| self.get(*name) ).collect() |
153 |
| - } |
154 |
| - |
155 |
| - pub fn packages(&self) -> &[Package] { &self.packages } |
156 |
| - |
157 |
| - // For now, assume that the package set contains only one package with a |
158 |
| - // given name |
159 |
| - pub fn sort(&self) -> Option<PackageSet> { |
160 |
| - let mut graph = graph::Graph::new(); |
161 |
| - |
162 |
| - for pkg in self.packages.iter() { |
163 |
| - let deps: Vec<&str> = pkg.dependencies().iter() |
164 |
| - .map(|dep| dep.name()) |
165 |
| - .collect(); |
166 |
| - |
167 |
| - graph.add(pkg.name(), &deps); |
| 127 | +impl<'cfg> PackageSet<'cfg> { |
| 128 | + pub fn new(package_ids: &[PackageId], |
| 129 | + sources: SourceMap<'cfg>) -> PackageSet<'cfg> { |
| 130 | + PackageSet { |
| 131 | + packages: package_ids.iter().map(|id| { |
| 132 | + (id.clone(), LazyCell::new(None)) |
| 133 | + }).collect(), |
| 134 | + sources: RefCell::new(sources), |
168 | 135 | }
|
169 |
| - |
170 |
| - let pkgs = match graph.sort() { |
171 |
| - Some(pkgs) => pkgs, |
172 |
| - None => return None, |
173 |
| - }; |
174 |
| - let pkgs = pkgs.iter().map(|name| { |
175 |
| - self.get(*name).clone() |
176 |
| - }).collect(); |
177 |
| - |
178 |
| - Some(PackageSet { |
179 |
| - packages: pkgs |
180 |
| - }) |
181 | 136 | }
|
182 | 137 |
|
183 |
| - pub fn iter(&self) -> slice::Iter<Package> { |
184 |
| - self.packages.iter() |
| 138 | + pub fn package_ids<'a>(&'a self) -> Box<Iterator<Item=&'a PackageId> + 'a> { |
| 139 | + Box::new(self.packages.iter().map(|&(ref p, _)| p)) |
185 | 140 | }
|
186 |
| -} |
187 | 141 |
|
188 |
| -impl Registry for PackageSet { |
189 |
| - fn query(&mut self, name: &Dependency) -> CargoResult<Vec<Summary>> { |
190 |
| - Ok(self.packages.iter() |
191 |
| - .filter(|pkg| name.name() == pkg.name()) |
192 |
| - .map(|pkg| pkg.summary().clone()) |
193 |
| - .collect()) |
| 142 | + pub fn get(&self, id: &PackageId) -> CargoResult<&Package> { |
| 143 | + let slot = try!(self.packages.iter().find(|p| p.0 == *id).chain_error(|| { |
| 144 | + internal(format!("couldn't find `{}` in package set", id)) |
| 145 | + })); |
| 146 | + let slot = &slot.1; |
| 147 | + if let Some(pkg) = slot.borrow() { |
| 148 | + return Ok(pkg) |
| 149 | + } |
| 150 | + let mut sources = self.sources.borrow_mut(); |
| 151 | + let source = try!(sources.get_mut(id.source_id()).chain_error(|| { |
| 152 | + internal(format!("couldn't find source for `{}`", id)) |
| 153 | + })); |
| 154 | + let pkg = try!(source.download(id).chain_error(|| { |
| 155 | + human("unable to get packages from source") |
| 156 | + })); |
| 157 | + assert!(slot.fill(pkg).is_ok()); |
| 158 | + Ok(slot.borrow().unwrap()) |
| 159 | + } |
| 160 | + |
| 161 | + pub fn sources(&self) -> Ref<SourceMap<'cfg>> { |
| 162 | + self.sources.borrow() |
194 | 163 | }
|
195 | 164 | }
|
0 commit comments