Skip to content

Commit

Permalink
Auto merge of #9547 - lu-zero:members_mut, r=alexcrichton
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Jun 9, 2021
2 parents aa8b092 + b26ceda commit 2b3af39
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 39 deletions.
2 changes: 1 addition & 1 deletion src/cargo/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
94 changes: 56 additions & 38 deletions src/cargo/core/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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`.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 2b3af39

Please sign in to comment.