|
1 | 1 | use crate::core::{Dependency, PackageId, SourceId}; |
2 | 2 | use crate::util::interning::InternedString; |
3 | 3 | use crate::util::CargoResult; |
| 4 | +use crate::util_schemas::manifest::FeatureName; |
4 | 5 | use crate::util_schemas::manifest::RustVersion; |
5 | 6 | use anyhow::bail; |
6 | 7 | use semver::Version; |
@@ -49,7 +50,7 @@ impl Summary { |
49 | 50 | ) |
50 | 51 | } |
51 | 52 | } |
52 | | - let feature_map = build_feature_map(pkg_id, features, &dependencies)?; |
| 53 | + let feature_map = build_feature_map(features, &dependencies)?; |
53 | 54 | Ok(Summary { |
54 | 55 | inner: Rc::new(Inner { |
55 | 56 | package_id: pkg_id, |
@@ -140,7 +141,6 @@ impl Hash for Summary { |
140 | 141 | /// Checks features for errors, bailing out a CargoResult:Err if invalid, |
141 | 142 | /// and creates FeatureValues for each feature. |
142 | 143 | fn build_feature_map( |
143 | | - pkg_id: PackageId, |
144 | 144 | features: &BTreeMap<InternedString, Vec<InternedString>>, |
145 | 145 | dependencies: &[Dependency], |
146 | 146 | ) -> CargoResult<FeatureMap> { |
@@ -191,19 +191,7 @@ fn build_feature_map( |
191 | 191 |
|
192 | 192 | // Validate features are listed properly. |
193 | 193 | for (feature, fvs) in &map { |
194 | | - if feature.starts_with("dep:") { |
195 | | - bail!( |
196 | | - "feature named `{}` is not allowed to start with `dep:`", |
197 | | - feature |
198 | | - ); |
199 | | - } |
200 | | - if feature.contains('/') { |
201 | | - bail!( |
202 | | - "feature named `{}` is not allowed to contain slashes", |
203 | | - feature |
204 | | - ); |
205 | | - } |
206 | | - validate_feature_name(pkg_id, feature)?; |
| 194 | + FeatureName::new(feature)?; |
207 | 195 | for fv in fvs { |
208 | 196 | // Find data for the referenced dependency... |
209 | 197 | let dep_data = { |
@@ -429,68 +417,3 @@ impl fmt::Display for FeatureValue { |
429 | 417 | } |
430 | 418 |
|
431 | 419 | pub type FeatureMap = BTreeMap<InternedString, Vec<FeatureValue>>; |
432 | | - |
433 | | -fn validate_feature_name(pkg_id: PackageId, name: &str) -> CargoResult<()> { |
434 | | - if name.is_empty() { |
435 | | - bail!("feature name cannot be empty"); |
436 | | - } |
437 | | - let mut chars = name.chars(); |
438 | | - if let Some(ch) = chars.next() { |
439 | | - if !(unicode_xid::UnicodeXID::is_xid_start(ch) || ch == '_' || ch.is_digit(10)) { |
440 | | - bail!( |
441 | | - "invalid character `{}` in feature `{}` in package {}, \ |
442 | | - the first character must be a Unicode XID start character or digit \ |
443 | | - (most letters or `_` or `0` to `9`)", |
444 | | - ch, |
445 | | - name, |
446 | | - pkg_id |
447 | | - ); |
448 | | - } |
449 | | - } |
450 | | - for ch in chars { |
451 | | - if !(unicode_xid::UnicodeXID::is_xid_continue(ch) || ch == '-' || ch == '+' || ch == '.') { |
452 | | - bail!( |
453 | | - "invalid character `{}` in feature `{}` in package {}, \ |
454 | | - characters must be Unicode XID characters, '-', `+`, or `.` \ |
455 | | - (numbers, `+`, `-`, `_`, `.`, or most letters)", |
456 | | - ch, |
457 | | - name, |
458 | | - pkg_id |
459 | | - ); |
460 | | - } |
461 | | - } |
462 | | - Ok(()) |
463 | | -} |
464 | | - |
465 | | -#[cfg(test)] |
466 | | -mod tests { |
467 | | - use super::*; |
468 | | - use crate::sources::CRATES_IO_INDEX; |
469 | | - use crate::util::into_url::IntoUrl; |
470 | | - |
471 | | - use crate::core::SourceId; |
472 | | - |
473 | | - #[test] |
474 | | - fn valid_feature_names() { |
475 | | - let loc = CRATES_IO_INDEX.into_url().unwrap(); |
476 | | - let source_id = SourceId::for_registry(&loc).unwrap(); |
477 | | - let pkg_id = PackageId::try_new("foo", "1.0.0", source_id).unwrap(); |
478 | | - |
479 | | - assert!(validate_feature_name(pkg_id, "c++17").is_ok()); |
480 | | - assert!(validate_feature_name(pkg_id, "128bit").is_ok()); |
481 | | - assert!(validate_feature_name(pkg_id, "_foo").is_ok()); |
482 | | - assert!(validate_feature_name(pkg_id, "feat-name").is_ok()); |
483 | | - assert!(validate_feature_name(pkg_id, "feat_name").is_ok()); |
484 | | - assert!(validate_feature_name(pkg_id, "foo.bar").is_ok()); |
485 | | - |
486 | | - assert!(validate_feature_name(pkg_id, "+foo").is_err()); |
487 | | - assert!(validate_feature_name(pkg_id, "-foo").is_err()); |
488 | | - assert!(validate_feature_name(pkg_id, ".foo").is_err()); |
489 | | - assert!(validate_feature_name(pkg_id, "foo:bar").is_err()); |
490 | | - assert!(validate_feature_name(pkg_id, "foo?").is_err()); |
491 | | - assert!(validate_feature_name(pkg_id, "?foo").is_err()); |
492 | | - assert!(validate_feature_name(pkg_id, "ⒶⒷⒸ").is_err()); |
493 | | - assert!(validate_feature_name(pkg_id, "a¼").is_err()); |
494 | | - assert!(validate_feature_name(pkg_id, "").is_err()); |
495 | | - } |
496 | | -} |
0 commit comments