Skip to content

Commit d7bcc0c

Browse files
committed
refactor(spec): Move queries to a extension trait
This is a step towards moving `PackageIdSpec` into `schema` as manifests need it as part of #12801. While I didn't take this approach in #13080, that was largely how core these functions are / how pervasive their use is.
1 parent 749654c commit d7bcc0c

File tree

14 files changed

+109
-84
lines changed

14 files changed

+109
-84
lines changed

src/bin/cargo/commands/remove.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use cargo::core::dependency::DepKind;
22
use cargo::core::PackageIdSpec;
3+
use cargo::core::PackageIdSpecQuery;
34
use cargo::core::Resolve;
45
use cargo::core::Workspace;
56
use cargo::ops::cargo_remove::remove;

src/cargo/core/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pub use self::manifest::{EitherManifest, VirtualManifest};
44
pub use self::manifest::{Manifest, Target, TargetKind};
55
pub use self::package::{Package, PackageSet};
66
pub use self::package_id::PackageId;
7-
pub use self::package_id_spec::PackageIdSpec;
7+
pub use self::package_id_spec::{PackageIdSpec, PackageIdSpecQuery};
88
pub use self::registry::Registry;
99
pub use self::resolver::{Resolve, ResolveVersion};
1010
pub use self::shell::{Shell, Verbosity};

src/cargo/core/package_id_spec.rs

Lines changed: 88 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -85,19 +85,6 @@ impl PackageIdSpec {
8585
})
8686
}
8787

88-
/// Roughly equivalent to `PackageIdSpec::parse(spec)?.query(i)`
89-
pub fn query_str<I>(spec: &str, i: I) -> CargoResult<PackageId>
90-
where
91-
I: IntoIterator<Item = PackageId>,
92-
{
93-
let i: Vec<_> = i.into_iter().collect();
94-
let spec = PackageIdSpec::parse(spec).with_context(|| {
95-
let suggestion = edit_distance::closest_msg(spec, i.iter(), |id| id.name().as_str());
96-
format!("invalid package ID specification: `{}`{}", spec, suggestion)
97-
})?;
98-
spec.query(i)
99-
}
100-
10188
/// Convert a `PackageId` to a `PackageIdSpec`, which will have both the `PartialVersion` and `Url`
10289
/// fields filled in.
10390
pub fn from_package_id(package_id: PackageId) -> PackageIdSpec {
@@ -221,9 +208,94 @@ impl PackageIdSpec {
221208
pub fn set_kind(&mut self, kind: SourceKind) {
222209
self.kind = Some(kind);
223210
}
211+
}
212+
213+
fn strip_url_protocol(url: &Url) -> Url {
214+
// Ridiculous hoop because `Url::set_scheme` errors when changing to http/https
215+
let raw = url.to_string();
216+
raw.split_once('+').unwrap().1.parse().unwrap()
217+
}
218+
219+
impl fmt::Display for PackageIdSpec {
220+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
221+
let mut printed_name = false;
222+
match self.url {
223+
Some(ref url) => {
224+
if let Some(protocol) = self.kind.as_ref().and_then(|k| k.protocol()) {
225+
write!(f, "{protocol}+")?;
226+
}
227+
write!(f, "{}", url)?;
228+
if let Some(SourceKind::Git(git_ref)) = self.kind.as_ref() {
229+
if let Some(pretty) = git_ref.pretty_ref(true) {
230+
write!(f, "?{}", pretty)?;
231+
}
232+
}
233+
if url.path_segments().unwrap().next_back().unwrap() != &*self.name {
234+
printed_name = true;
235+
write!(f, "#{}", self.name)?;
236+
}
237+
}
238+
None => {
239+
printed_name = true;
240+
write!(f, "{}", self.name)?;
241+
}
242+
}
243+
if let Some(ref v) = self.version {
244+
write!(f, "{}{}", if printed_name { "@" } else { "#" }, v)?;
245+
}
246+
Ok(())
247+
}
248+
}
249+
250+
impl ser::Serialize for PackageIdSpec {
251+
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
252+
where
253+
S: ser::Serializer,
254+
{
255+
self.to_string().serialize(s)
256+
}
257+
}
258+
259+
impl<'de> de::Deserialize<'de> for PackageIdSpec {
260+
fn deserialize<D>(d: D) -> Result<PackageIdSpec, D::Error>
261+
where
262+
D: de::Deserializer<'de>,
263+
{
264+
let string = String::deserialize(d)?;
265+
PackageIdSpec::parse(&string).map_err(de::Error::custom)
266+
}
267+
}
268+
269+
pub trait PackageIdSpecQuery {
270+
/// Roughly equivalent to `PackageIdSpec::parse(spec)?.query(i)`
271+
fn query_str<I>(spec: &str, i: I) -> CargoResult<PackageId>
272+
where
273+
I: IntoIterator<Item = PackageId>;
224274

225275
/// Checks whether the given `PackageId` matches the `PackageIdSpec`.
226-
pub fn matches(&self, package_id: PackageId) -> bool {
276+
fn matches(&self, package_id: PackageId) -> bool;
277+
278+
/// Checks a list of `PackageId`s to find 1 that matches this `PackageIdSpec`. If 0, 2, or
279+
/// more are found, then this returns an error.
280+
fn query<I>(&self, i: I) -> CargoResult<PackageId>
281+
where
282+
I: IntoIterator<Item = PackageId>;
283+
}
284+
285+
impl PackageIdSpecQuery for PackageIdSpec {
286+
fn query_str<I>(spec: &str, i: I) -> CargoResult<PackageId>
287+
where
288+
I: IntoIterator<Item = PackageId>,
289+
{
290+
let i: Vec<_> = i.into_iter().collect();
291+
let spec = PackageIdSpec::parse(spec).with_context(|| {
292+
let suggestion = edit_distance::closest_msg(spec, i.iter(), |id| id.name().as_str());
293+
format!("invalid package ID specification: `{}`{}", spec, suggestion)
294+
})?;
295+
spec.query(i)
296+
}
297+
298+
fn matches(&self, package_id: PackageId) -> bool {
227299
if self.name() != package_id.name().as_str() {
228300
return false;
229301
}
@@ -249,9 +321,7 @@ impl PackageIdSpec {
249321
true
250322
}
251323

252-
/// Checks a list of `PackageId`s to find 1 that matches this `PackageIdSpec`. If 0, 2, or
253-
/// more are found, then this returns an error.
254-
pub fn query<I>(&self, i: I) -> CargoResult<PackageId>
324+
fn query<I>(&self, i: I) -> CargoResult<PackageId>
255325
where
256326
I: IntoIterator<Item = PackageId>,
257327
{
@@ -342,65 +412,10 @@ impl PackageIdSpec {
342412
}
343413
}
344414

345-
fn strip_url_protocol(url: &Url) -> Url {
346-
// Ridiculous hoop because `Url::set_scheme` errors when changing to http/https
347-
let raw = url.to_string();
348-
raw.split_once('+').unwrap().1.parse().unwrap()
349-
}
350-
351-
impl fmt::Display for PackageIdSpec {
352-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
353-
let mut printed_name = false;
354-
match self.url {
355-
Some(ref url) => {
356-
if let Some(protocol) = self.kind.as_ref().and_then(|k| k.protocol()) {
357-
write!(f, "{protocol}+")?;
358-
}
359-
write!(f, "{}", url)?;
360-
if let Some(SourceKind::Git(git_ref)) = self.kind.as_ref() {
361-
if let Some(pretty) = git_ref.pretty_ref(true) {
362-
write!(f, "?{}", pretty)?;
363-
}
364-
}
365-
if url.path_segments().unwrap().next_back().unwrap() != &*self.name {
366-
printed_name = true;
367-
write!(f, "#{}", self.name)?;
368-
}
369-
}
370-
None => {
371-
printed_name = true;
372-
write!(f, "{}", self.name)?;
373-
}
374-
}
375-
if let Some(ref v) = self.version {
376-
write!(f, "{}{}", if printed_name { "@" } else { "#" }, v)?;
377-
}
378-
Ok(())
379-
}
380-
}
381-
382-
impl ser::Serialize for PackageIdSpec {
383-
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
384-
where
385-
S: ser::Serializer,
386-
{
387-
self.to_string().serialize(s)
388-
}
389-
}
390-
391-
impl<'de> de::Deserialize<'de> for PackageIdSpec {
392-
fn deserialize<D>(d: D) -> Result<PackageIdSpec, D::Error>
393-
where
394-
D: de::Deserializer<'de>,
395-
{
396-
let string = String::deserialize(d)?;
397-
PackageIdSpec::parse(&string).map_err(de::Error::custom)
398-
}
399-
}
400-
401415
#[cfg(test)]
402416
mod tests {
403417
use super::PackageIdSpec;
418+
use super::PackageIdSpecQuery;
404419
use crate::core::{GitReference, PackageId, SourceId, SourceKind};
405420
use url::Url;
406421

src/cargo/core/profiles.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ use crate::core::compiler::{CompileKind, CompileTarget, Unit};
2525
use crate::core::dependency::Artifact;
2626
use crate::core::resolver::features::FeaturesFor;
2727
use crate::core::Feature;
28-
use crate::core::{PackageId, PackageIdSpec, Resolve, Shell, Target, Workspace};
28+
use crate::core::{
29+
PackageId, PackageIdSpec, PackageIdSpecQuery, Resolve, Shell, Target, Workspace,
30+
};
2931
use crate::util::interning::InternedString;
3032
use crate::util::toml::validate_profile;
3133
use crate::util::{closest_msg, config, CargoResult, Config};

src/cargo/core/resolver/dep_cache.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ use crate::core::resolver::{
1616
ActivateError, ActivateResult, CliFeatures, RequestedFeatures, ResolveOpts, VersionOrdering,
1717
VersionPreferences,
1818
};
19-
use crate::core::{Dependency, FeatureValue, PackageId, PackageIdSpec, Registry, Summary};
19+
use crate::core::{
20+
Dependency, FeatureValue, PackageId, PackageIdSpec, PackageIdSpecQuery, Registry, Summary,
21+
};
2022
use crate::sources::source::QueryKind;
2123
use crate::util::errors::CargoResult;
2224
use crate::util::interning::InternedString;

src/cargo/core/resolver/resolve.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::encode::Metadata;
22
use crate::core::dependency::DepKind;
3-
use crate::core::{Dependency, PackageId, PackageIdSpec, Summary, Target};
3+
use crate::core::{Dependency, PackageId, PackageIdSpec, PackageIdSpecQuery, Summary, Target};
44
use crate::util::errors::CargoResult;
55
use crate::util::interning::InternedString;
66
use crate::util::Graph;

src/cargo/core/workspace.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ use crate::core::features::Features;
1515
use crate::core::registry::PackageRegistry;
1616
use crate::core::resolver::features::CliFeatures;
1717
use crate::core::resolver::ResolveBehavior;
18-
use crate::core::{Dependency, Edition, FeatureValue, PackageId, PackageIdSpec};
18+
use crate::core::{
19+
Dependency, Edition, FeatureValue, PackageId, PackageIdSpec, PackageIdSpecQuery,
20+
};
1921
use crate::core::{EitherManifest, Package, SourceId, VirtualManifest};
2022
use crate::ops;
2123
use crate::sources::{PathSource, CRATES_IO_INDEX, CRATES_IO_REGISTRY};

src/cargo/ops/cargo_clean.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::core::compiler::{CompileKind, CompileMode, Layout, RustcTargetData};
22
use crate::core::profiles::Profiles;
3-
use crate::core::{PackageIdSpec, TargetKind, Workspace};
3+
use crate::core::{PackageIdSpec, PackageIdSpecQuery, TargetKind, Workspace};
44
use crate::ops;
55
use crate::util::edit_distance;
66
use crate::util::errors::CargoResult;

src/cargo/ops/cargo_generate_lockfile.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::core::registry::PackageRegistry;
22
use crate::core::resolver::features::{CliFeatures, HasDevUnits};
3-
use crate::core::{PackageId, PackageIdSpec};
3+
use crate::core::{PackageId, PackageIdSpec, PackageIdSpecQuery};
44
use crate::core::{Resolve, SourceId, Workspace};
55
use crate::ops;
66
use crate::util::cache_lock::CacheLockMode;

src/cargo/ops/cargo_pkgid.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::core::{PackageIdSpec, Workspace};
1+
use crate::core::{PackageIdSpec, PackageIdSpecQuery, Workspace};
22
use crate::ops;
33
use crate::util::CargoResult;
44

0 commit comments

Comments
 (0)