Skip to content

Commit

Permalink
Allow features with '/' in the name
Browse files Browse the repository at this point in the history
These are just reexported features.

Closes rust-lang/cargo#963
  • Loading branch information
alexcrichton committed Nov 24, 2014
1 parent 860be95 commit d64528f
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
14 changes: 14 additions & 0 deletions src/krate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,20 @@ impl Crate {
name.chars().all(|c| c.is_ascii())
}

pub fn valid_feature_name(name: &str) -> bool {
let mut parts = name.split('/');
match parts.next() {
Some(part) if !Crate::valid_name(part) => return false,
None => return false,
_ => {}
}
match parts.next() {
Some(part) if !Crate::valid_name(part) => return false,
_ => {}
}
parts.next().is_none()
}

pub fn encodable(self, versions: Option<Vec<i32>>) -> EncodableCrate {
let Crate {
name, created_at, updated_at, downloads, max_version, description,
Expand Down
9 changes: 9 additions & 0 deletions src/tests/krate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,15 @@ fn new_crate_owner() {
::json::<GoodCrate>(&mut response);
}

#[test]
fn valid_feature_names() {
assert!(Crate::valid_feature_name("foo"));
assert!(!Crate::valid_feature_name(""));
assert!(!Crate::valid_feature_name("/"));
assert!(!Crate::valid_feature_name("%/%"));
assert!(Crate::valid_feature_name("a/a"));
}

#[test]
fn new_krate_too_big() {
let (_b, app, middle) = ::app();
Expand Down
27 changes: 26 additions & 1 deletion src/upload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ pub struct CrateVersion(pub semver::Version);
pub struct CrateVersionReq(pub semver::VersionReq);
pub struct KeywordList(pub Vec<Keyword>);
pub struct Keyword(pub String);
pub struct Feature(pub String);

#[deriving(Decodable, Encodable)]
pub struct CrateDependency {
pub optional: bool,
pub default_features: bool,
pub name: CrateName,
pub features: Vec<CrateName>,
pub features: Vec<Feature>,
pub version_req: CrateVersionReq,
pub target: Option<String>,
pub kind: Option<DependencyKind>,
Expand Down Expand Up @@ -63,6 +64,17 @@ impl<E, D: Decoder<E>> Decodable<D, E> for Keyword {
}
}

impl<E, D: Decoder<E>> Decodable<D, E> for Feature {
fn decode(d: &mut D) -> Result<Feature, E> {
let s = raw_try!(d.read_str());
if !Crate::valid_feature_name(s.as_slice()) {
return Err(d.error(format!("invalid feature name specified: {}",
s).as_slice()))
}
Ok(Feature(s))
}
}

impl<E, D: Decoder<E>> Decodable<D, E> for CrateVersion {
fn decode(d: &mut D) -> Result<CrateVersion, E> {
let s = raw_try!(d.read_str());
Expand Down Expand Up @@ -126,6 +138,12 @@ impl<E, D: Encoder<E>> Encodable<D, E> for Keyword {
}
}

impl<E, D: Encoder<E>> Encodable<D, E> for Feature {
fn encode(&self, d: &mut D) -> Result<(), E> {
d.emit_str(self.as_slice())
}
}

impl<E, D: Encoder<E>> Encodable<D, E> for CrateVersion {
fn encode(&self, d: &mut D) -> Result<(), E> {
d.emit_str((**self).to_string().as_slice())
Expand Down Expand Up @@ -169,6 +187,13 @@ impl Deref<str> for Keyword {
}
}

impl Deref<str> for Feature {
fn deref<'a>(&'a self) -> &'a str {
let Feature(ref s) = *self;
s.as_slice()
}
}

impl Deref<semver::Version> for CrateVersion {
fn deref<'a>(&'a self) -> &'a semver::Version {
let CrateVersion(ref s) = *self; s
Expand Down

0 comments on commit d64528f

Please sign in to comment.