From c14bb6e07314705f8f46cc9a4855d8e004f6e79d Mon Sep 17 00:00:00 2001 From: Eh2406 Date: Thu, 29 Aug 2019 15:16:18 -0400 Subject: [PATCH] minimal-copy `deserialize` for `InternedString` and use `InternedString` more places --- crates/resolver-tests/src/lib.rs | 2 +- crates/resolver-tests/tests/resolve.rs | 2 -- src/cargo/core/dependency.rs | 26 ++++++++------- src/cargo/core/interning.rs | 44 ++++++++++++++++++++++++++ src/cargo/core/package_id.rs | 8 +++-- src/cargo/core/registry.rs | 2 +- src/cargo/core/resolver/dep_cache.rs | 2 +- src/cargo/core/summary.rs | 4 +-- src/cargo/sources/registry/index.rs | 2 +- src/cargo/sources/registry/mod.rs | 21 ++++++------ src/cargo/util/toml/mod.rs | 6 ++-- 11 files changed, 84 insertions(+), 35 deletions(-) diff --git a/crates/resolver-tests/src/lib.rs b/crates/resolver-tests/src/lib.rs index dce94689e..c77a05075 100644 --- a/crates/resolver-tests/src/lib.rs +++ b/crates/resolver-tests/src/lib.rs @@ -171,7 +171,7 @@ pub fn resolve_with_config_raw( pkg_id("root"), deps, &BTreeMap::>::new(), - None::, + None::<&String>, false, ) .unwrap(); diff --git a/crates/resolver-tests/tests/resolve.rs b/crates/resolver-tests/tests/resolve.rs index 0c6512186..362a6dc9b 100644 --- a/crates/resolver-tests/tests/resolve.rs +++ b/crates/resolver-tests/tests/resolve.rs @@ -1,5 +1,3 @@ -use std::env; - use cargo::core::dependency::Kind; use cargo::core::{enable_nightly_features, Dependency}; use cargo::util::{is_ci, Config}; diff --git a/src/cargo/core/dependency.rs b/src/cargo/core/dependency.rs index 1da54590e..0624b0980 100644 --- a/src/cargo/core/dependency.rs +++ b/src/cargo/core/dependency.rs @@ -101,7 +101,7 @@ pub enum Kind { } fn parse_req_with_deprecated( - name: &str, + name: InternedString, req: &str, extra: Option<(PackageId, &Config)>, ) -> CargoResult { @@ -163,12 +163,13 @@ impl ser::Serialize for Kind { impl Dependency { /// Attempt to create a `Dependency` from an entry in the manifest. pub fn parse( - name: &str, + name: impl Into, version: Option<&str>, source_id: SourceId, inside: PackageId, config: &Config, ) -> CargoResult { + let name = name.into(); let arg = Some((inside, config)); let (specified_req, version_req) = match version { Some(v) => (true, parse_req_with_deprecated(name, v, arg)?), @@ -187,10 +188,11 @@ impl Dependency { /// Attempt to create a `Dependency` from an entry in the manifest. pub fn parse_no_deprecated( - name: &str, + name: impl Into, version: Option<&str>, source_id: SourceId, ) -> CargoResult { + let name = name.into(); let (specified_req, version_req) = match version { Some(v) => (true, parse_req_with_deprecated(name, v, None)?), None => (false, VersionReq::any()), @@ -206,11 +208,11 @@ impl Dependency { Ok(ret) } - pub fn new_override(name: &str, source_id: SourceId) -> Dependency { + pub fn new_override(name: InternedString, source_id: SourceId) -> Dependency { assert!(!name.is_empty()); Dependency { inner: Rc::new(Inner { - name: InternedString::new(name), + name, source_id, registry_id: None, req: VersionReq::any(), @@ -338,12 +340,9 @@ impl Dependency { /// Sets the list of features requested for the package. pub fn set_features( &mut self, - features: impl IntoIterator>, + features: impl IntoIterator>, ) -> &mut Dependency { - Rc::make_mut(&mut self.inner).features = features - .into_iter() - .map(|s| InternedString::new(s.as_ref())) - .collect(); + Rc::make_mut(&mut self.inner).features = features.into_iter().map(|s| s.into()).collect(); self } @@ -376,8 +375,11 @@ impl Dependency { self } - pub fn set_explicit_name_in_toml(&mut self, name: &str) -> &mut Dependency { - Rc::make_mut(&mut self.inner).explicit_name_in_toml = Some(InternedString::new(name)); + pub fn set_explicit_name_in_toml( + &mut self, + name: impl Into, + ) -> &mut Dependency { + Rc::make_mut(&mut self.inner).explicit_name_in_toml = Some(name.into()); self } diff --git a/src/cargo/core/interning.rs b/src/cargo/core/interning.rs index c5f975044..f4223f414 100644 --- a/src/cargo/core/interning.rs +++ b/src/cargo/core/interning.rs @@ -23,6 +23,18 @@ pub struct InternedString { inner: &'static str, } +impl<'a> From<&'a str> for InternedString { + fn from(item: &'a str) -> Self { + InternedString::new(item) + } +} + +impl<'a> From<&'a String> for InternedString { + fn from(item: &'a String) -> Self { + InternedString::new(item) + } +} + impl PartialEq for InternedString { fn eq(&self, other: &InternedString) -> bool { ptr::eq(self.as_str(), other.as_str()) @@ -56,6 +68,12 @@ impl Deref for InternedString { } } +impl AsRef for InternedString { + fn as_ref(&self) -> &str { + self.as_str() + } +} + impl Hash for InternedString { // N.B., we can't implement this as `identity(self).hash(state)`, // because we use this for on-disk fingerprints and so need @@ -105,3 +123,29 @@ impl Serialize for InternedString { serializer.serialize_str(self.inner) } } + +struct InternedStringVisitor; + +impl<'de> serde::Deserialize<'de> for InternedString { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_str(InternedStringVisitor) + } +} + +impl<'de> serde::de::Visitor<'de> for InternedStringVisitor { + type Value = InternedString; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("an String like thing") + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + Ok(InternedString::new(v)) + } +} diff --git a/src/cargo/core/package_id.rs b/src/cargo/core/package_id.rs index 208c3ba3e..8c40e9dd9 100644 --- a/src/cargo/core/package_id.rs +++ b/src/cargo/core/package_id.rs @@ -113,9 +113,13 @@ impl Hash for PackageId { } impl PackageId { - pub fn new(name: &str, version: T, sid: SourceId) -> CargoResult { + pub fn new( + name: impl Into, + version: T, + sid: SourceId, + ) -> CargoResult { let v = version.to_semver()?; - Ok(PackageId::pure(InternedString::new(name), v, sid)) + Ok(PackageId::pure(name.into(), v, sid)) } pub fn pure(name: InternedString, version: semver::Version, source_id: SourceId) -> PackageId { diff --git a/src/cargo/core/registry.rs b/src/cargo/core/registry.rs index 54468d9f8..979e54759 100644 --- a/src/cargo/core/registry.rs +++ b/src/cargo/core/registry.rs @@ -366,7 +366,7 @@ impl<'cfg> PackageRegistry<'cfg> { fn query_overrides(&mut self, dep: &Dependency) -> CargoResult> { for &s in self.overrides.iter() { let src = self.sources.get_mut(s).unwrap(); - let dep = Dependency::new_override(&*dep.package_name(), s); + let dep = Dependency::new_override(dep.package_name(), s); let mut results = src.query_vec(&dep)?; if !results.is_empty() { return Ok(Some(results.remove(0))); diff --git a/src/cargo/core/resolver/dep_cache.rs b/src/cargo/core/resolver/dep_cache.rs index ccfde1ade..aa33b1b0c 100644 --- a/src/cargo/core/resolver/dep_cache.rs +++ b/src/cargo/core/resolver/dep_cache.rs @@ -433,7 +433,7 @@ impl Requirements<'_> { for fv in self .summary .features() - .get(feat.as_str()) + .get(&feat) .expect("must be a valid feature") { match *fv { diff --git a/src/cargo/core/summary.rs b/src/cargo/core/summary.rs index fb52b9179..7080d2274 100644 --- a/src/cargo/core/summary.rs +++ b/src/cargo/core/summary.rs @@ -37,7 +37,7 @@ impl Summary { pkg_id: PackageId, dependencies: Vec, features: &BTreeMap>>, - links: Option>, + links: Option>, namespaced_features: bool, ) -> CargoResult where @@ -66,7 +66,7 @@ impl Summary { dependencies, features: feature_map, checksum: None, - links: links.map(|l| InternedString::new(l.as_ref())), + links: links.map(|l| l.into()), namespaced_features, }), }) diff --git a/src/cargo/sources/registry/index.rs b/src/cargo/sources/registry/index.rs index accc40deb..597c39e38 100644 --- a/src/cargo/sources/registry/index.rs +++ b/src/cargo/sources/registry/index.rs @@ -716,7 +716,7 @@ impl IndexSummary { links, } = serde_json::from_slice(line)?; log::trace!("json parsed registry {}/{}", name, vers); - let pkgid = PackageId::new(&name, &vers, source_id)?; + let pkgid = PackageId::new(name, &vers, source_id)?; let deps = deps .into_iter() .map(|dep| dep.into_dep(source_id)) diff --git a/src/cargo/sources/registry/mod.rs b/src/cargo/sources/registry/mod.rs index a63d15e01..7b28e9ae5 100644 --- a/src/cargo/sources/registry/mod.rs +++ b/src/cargo/sources/registry/mod.rs @@ -219,17 +219,18 @@ pub struct RegistryConfig { #[derive(Deserialize)] pub struct RegistryPackage<'a> { - name: Cow<'a, str>, + name: InternedString, vers: Version, + #[serde(borrow)] deps: Vec>, - features: BTreeMap, Vec>>, + features: BTreeMap>, cksum: String, yanked: Option, - links: Option>, + links: Option, } #[test] -fn escaped_cher_in_json() { +fn escaped_char_in_json() { let _: RegistryPackage<'_> = serde_json::from_str( r#"{"name":"a","vers":"0.0.1","deps":[],"cksum":"bae3","features":{}}"#, ) @@ -275,15 +276,16 @@ enum Field { #[derive(Deserialize)] struct RegistryDependency<'a> { - name: Cow<'a, str>, + name: InternedString, + #[serde(borrow)] req: Cow<'a, str>, - features: Vec>, + features: Vec, optional: bool, default_features: bool, target: Option>, kind: Option>, registry: Option>, - package: Option>, + package: Option, public: Option, } @@ -309,10 +311,9 @@ impl<'a> RegistryDependency<'a> { default }; - let mut dep = - Dependency::parse_no_deprecated(package.as_ref().unwrap_or(&name), Some(&req), id)?; + let mut dep = Dependency::parse_no_deprecated(package.unwrap_or(name), Some(&req), id)?; if package.is_some() { - dep.set_explicit_name_in_toml(&name); + dep.set_explicit_name_in_toml(name); } let kind = match kind.as_ref().map(|s| &s[..]).unwrap_or("") { "dev" => Kind::Development, diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 5d9e000b8..dd4da3e6e 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -16,7 +16,7 @@ use url::Url; use crate::core::dependency::{Kind, Platform}; use crate::core::manifest::{LibKind, ManifestMetadata, TargetSourcePath, Warnings}; use crate::core::profiles::Profiles; -use crate::core::{Dependency, Manifest, PackageId, Summary, Target}; +use crate::core::{Dependency, InternedString, Manifest, PackageId, Summary, Target}; use crate::core::{Edition, EitherManifest, Feature, Features, VirtualManifest}; use crate::core::{GitReference, PackageIdSpec, SourceId, WorkspaceConfig, WorkspaceRootConfig}; use crate::sources::{CRATES_IO_INDEX, CRATES_IO_REGISTRY}; @@ -650,7 +650,7 @@ impl<'de> de::Deserialize<'de> for VecStringOrBool { #[derive(Deserialize, Serialize, Clone, Debug)] pub struct TomlProject { edition: Option, - name: String, + name: InternedString, version: semver::Version, authors: Option>, build: Option, @@ -697,7 +697,7 @@ pub struct TomlWorkspace { impl TomlProject { pub fn to_package_id(&self, source_id: SourceId) -> CargoResult { - PackageId::new(&self.name, self.version.clone(), source_id) + PackageId::new(self.name, self.version.clone(), source_id) } } -- 2.39.5