Auto merge of #9547 - lu-zero:members_mut, r=alexcrichton

Add a mean to mutably access the members of a workspace

It is used by cargo-c to patch all the lib crates in a workspace.
This commit is contained in:
bors 2021-06-09 15:06:38 +00:00
commit 2b3af39167
2 changed files with 57 additions and 39 deletions

View File

@ -10,7 +10,7 @@ pub use self::resolver::{Resolve, ResolveVersion};
pub use self::shell::{Shell, Verbosity};
pub use self::source::{GitReference, Source, SourceId, SourceMap};
pub use self::summary::{FeatureMap, FeatureValue, Summary};
pub use self::workspace::{MaybePackage, Members, Workspace, WorkspaceConfig, WorkspaceRootConfig};
pub use self::workspace::{MaybePackage, Workspace, WorkspaceConfig, WorkspaceRootConfig};
pub mod compiler;
pub mod dependency;

View File

@ -3,7 +3,6 @@ use std::collections::hash_map::{Entry, HashMap};
use std::collections::{BTreeMap, BTreeSet, HashSet};
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::slice;
use anyhow::{bail, Context as _};
use glob::glob;
@ -136,13 +135,6 @@ pub struct WorkspaceRootConfig {
custom_metadata: Option<toml::Value>,
}
/// An iterator over the member packages of a workspace, returned by
/// `Workspace::members`
pub struct Members<'a, 'cfg> {
ws: &'a Workspace<'cfg>,
iter: slice::Iter<'a, PathBuf>,
}
impl<'cfg> Workspace<'cfg> {
/// Creates a new workspace given the target manifest pointed to by
/// `manifest_path`.
@ -466,19 +458,65 @@ impl<'cfg> Workspace<'cfg> {
}
/// Returns an iterator over all packages in this workspace
pub fn members<'a>(&'a self) -> Members<'a, 'cfg> {
Members {
ws: self,
iter: self.members.iter(),
}
pub fn members(&self) -> impl Iterator<Item = &Package> {
let packages = &self.packages;
self.members
.iter()
.filter_map(move |path| match packages.get(path) {
&MaybePackage::Package(ref p) => Some(p),
_ => None,
})
}
/// Returns a mutable iterator over all packages in this workspace
pub fn members_mut(&mut self) -> impl Iterator<Item = &mut Package> {
let packages = &mut self.packages.packages;
let members: HashSet<_> = self
.members
.iter()
.map(|path| path.parent().unwrap().to_owned())
.collect();
packages.iter_mut().filter_map(move |(path, package)| {
if members.contains(path) {
if let MaybePackage::Package(ref mut p) = package {
return Some(p);
}
}
None
})
}
/// Returns an iterator over default packages in this workspace
pub fn default_members<'a>(&'a self) -> Members<'a, 'cfg> {
Members {
ws: self,
iter: self.default_members.iter(),
}
pub fn default_members<'a>(&'a self) -> impl Iterator<Item = &Package> {
let packages = &self.packages;
self.default_members
.iter()
.filter_map(move |path| match packages.get(path) {
&MaybePackage::Package(ref p) => Some(p),
_ => None,
})
}
/// Returns an iterator over default packages in this workspace
pub fn default_members_mut(&mut self) -> impl Iterator<Item = &mut Package> {
let packages = &mut self.packages.packages;
let members: HashSet<_> = self
.default_members
.iter()
.map(|path| path.parent().unwrap().to_owned())
.collect();
packages.iter_mut().filter_map(move |(path, package)| {
if members.contains(path) {
if let MaybePackage::Package(ref mut p) = package {
return Some(p);
}
}
None
})
}
/// Returns true if the package is a member of the workspace.
@ -1529,26 +1567,6 @@ impl<'cfg> Packages<'cfg> {
}
}
impl<'a, 'cfg> Iterator for Members<'a, 'cfg> {
type Item = &'a Package;
fn next(&mut self) -> Option<&'a Package> {
loop {
let next = self.iter.next().map(|path| self.ws.packages.get(path));
match next {
Some(&MaybePackage::Package(ref p)) => return Some(p),
Some(&MaybePackage::Virtual(_)) => {}
None => return None,
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
}
impl MaybePackage {
fn workspace_config(&self) -> &WorkspaceConfig {
match *self {