From eebbfa0286cf479a200f0f558aaa8472ea24cb2d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 26 Aug 2014 08:45:33 -0700 Subject: [PATCH] Decode directly into a semver::Version This generates errors for malformed semver versions during the decoding process rather than later in the convertion to a package id. This also cuts down on the large number of derived traits to only what's necessary. Closes #54 --- src/cargo/util/toml.rs | 44 +++++++++++++++++++++++++------------ tests/test_cargo_compile.rs | 3 ++- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/cargo/util/toml.rs b/src/cargo/util/toml.rs index 03445dccd..c7231a609 100644 --- a/src/cargo/util/toml.rs +++ b/src/cargo/util/toml.rs @@ -1,10 +1,11 @@ -use serialize::Decodable; use std::collections::HashMap; use std::fmt; use std::io::fs; use std::slice; use std::str; use toml; +use semver; +use serialize::{Decodable, Decoder}; use core::{SourceId, GitKind}; use core::manifest::{LibKind, Lib, Dylib, Profile}; @@ -168,14 +169,14 @@ type TomlBenchTarget = TomlTarget; * TODO: Make all struct fields private */ -#[deriving(Encodable,Decodable,PartialEq,Clone,Show)] +#[deriving(Decodable)] pub enum TomlDependency { SimpleDep(String), DetailedDep(DetailedTomlDependency) } -#[deriving(Encodable,Decodable,PartialEq,Clone,Show)] +#[deriving(Decodable)] pub struct DetailedTomlDependency { version: Option, path: Option, @@ -185,7 +186,7 @@ pub struct DetailedTomlDependency { rev: Option } -#[deriving(Encodable,Decodable,PartialEq,Clone)] +#[deriving(Decodable)] pub struct TomlManifest { package: Option>, project: Option>, @@ -198,7 +199,7 @@ pub struct TomlManifest { dev_dependencies: Option>, } -#[deriving(Encodable,Decodable,PartialEq,Clone)] +#[deriving(Decodable)] pub enum ManyOrOne { Many(Vec), One(T), @@ -213,25 +214,40 @@ impl ManyOrOne { } } -#[deriving(Decodable,Encodable,PartialEq,Clone,Show)] +#[deriving(Decodable)] pub struct TomlProject { - pub name: String, - // FIXME #54: should be a Version to be able to be Decodable'd directly. - pub version: String, + name: String, + version: TomlVersion, pub authors: Vec, build: Option, exclude: Option>, } -#[deriving(Encodable,Decodable,PartialEq,Clone,Show)] +#[deriving(Decodable)] pub enum TomlBuildCommandsList { SingleBuildCommand(String), MultipleBuildCommands(Vec) } +pub struct TomlVersion { + version: semver::Version, +} + +impl> Decodable for TomlVersion { + fn decode(d: &mut D) -> Result { + let s = raw_try!(d.read_str()); + match semver::parse(s.as_slice()) { + Some(s) => Ok(TomlVersion { version: s }), + None => Err(d.error(format!("cannot parse '{}' as a semver", + s).as_slice())), + } + } +} + impl TomlProject { pub fn to_package_id(&self, source_id: &SourceId) -> CargoResult { - PackageId::new(self.name.as_slice(), self.version.as_slice(), source_id) + PackageId::new(self.name.as_slice(), self.version.version.clone(), + source_id) } } @@ -395,7 +411,7 @@ impl TomlManifest { &metadata); if targets.is_empty() { - debug!("manifest has no build targets; project={}", self.project); + debug!("manifest has no build targets"); } let mut deps = Vec::new(); @@ -490,7 +506,7 @@ fn process_dependencies<'a>(cx: &mut Context<'a>, dev: bool, Ok(()) } -#[deriving(Decodable,Encodable,PartialEq,Clone,Show)] +#[deriving(Decodable, Show, Clone)] struct TomlTarget { name: String, crate_type: Option>, @@ -502,7 +518,7 @@ struct TomlTarget { plugin: Option, } -#[deriving(Decodable,Encodable,PartialEq,Clone)] +#[deriving(Decodable, Clone)] enum TomlPath { TomlString(String), TomlPath(Path), diff --git a/tests/test_cargo_compile.rs b/tests/test_cargo_compile.rs index 7bf37e965..94de1535d 100644 --- a/tests/test_cargo_compile.rs +++ b/tests/test_cargo_compile.rs @@ -76,7 +76,8 @@ test!(cargo_compile_with_invalid_version { execs() .with_status(101) .with_stderr("Cargo.toml is not a valid manifest\n\n\ - invalid version: cannot parse '1.0' as a semver\n")) + cannot parse '1.0' as a semver for the key \ + `project.version`\n")) })