Skip to content

Commit 44a31d6

Browse files
committed
Simplify cargo-new configuration reading
No need for lots of extra helpers/parsing when using serde!
1 parent d7d8ca1 commit 44a31d6

File tree

1 file changed

+37
-36
lines changed

1 file changed

+37
-36
lines changed

src/cargo/ops/cargo_new.rs

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1+
use crate::core::{compiler, Workspace};
2+
use crate::util::errors::{self, CargoResult, CargoResultExt};
3+
use crate::util::{existing_vcs_repo, FossilRepo, GitRepo, HgRepo, PijulRepo};
4+
use crate::util::{paths, validate_package_name, Config};
5+
use git2::Config as GitConfig;
6+
use git2::Repository as GitRepository;
7+
use serde::de;
8+
use serde::Deserialize;
19
use std::collections::BTreeMap;
210
use std::env;
311
use std::fmt;
412
use std::fs;
513
use std::io::{BufRead, BufReader, ErrorKind};
614
use std::path::{Path, PathBuf};
7-
8-
use git2::Config as GitConfig;
9-
use git2::Repository as GitRepository;
10-
11-
use crate::core::{compiler, Workspace};
12-
use crate::util::errors::{self, CargoResult, CargoResultExt};
13-
use crate::util::{existing_vcs_repo, internal, FossilRepo, GitRepo, HgRepo, PijulRepo};
14-
use crate::util::{paths, validate_package_name, Config};
15+
use std::str::FromStr;
1516

1617
use toml;
1718

@@ -24,6 +25,31 @@ pub enum VersionControl {
2425
NoVcs,
2526
}
2627

28+
impl FromStr for VersionControl {
29+
type Err = failure::Error;
30+
31+
fn from_str(s: &str) -> Result<Self, failure::Error> {
32+
match s {
33+
"git" => Ok(VersionControl::Git),
34+
"hg" => Ok(VersionControl::Hg),
35+
"pijul" => Ok(VersionControl::Pijul),
36+
"fossil" => Ok(VersionControl::Fossil),
37+
"none" => Ok(VersionControl::NoVcs),
38+
other => failure::bail!("unknown vcs specification: `{}`", other),
39+
}
40+
}
41+
}
42+
43+
impl<'de> de::Deserialize<'de> for VersionControl {
44+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
45+
where
46+
D: de::Deserializer<'de>,
47+
{
48+
let s = String::deserialize(deserializer)?;
49+
FromStr::from_str(&s).map_err(de::Error::custom)
50+
}
51+
}
52+
2753
#[derive(Debug)]
2854
pub struct NewOptions {
2955
pub version_control: Option<VersionControl>,
@@ -102,9 +128,11 @@ impl NewOptions {
102128
}
103129
}
104130

131+
#[derive(Deserialize)]
105132
struct CargoNewConfig {
106133
name: Option<String>,
107134
email: Option<String>,
135+
#[serde(rename = "vcs")]
108136
version_control: Option<VersionControl>,
109137
}
110138

@@ -543,7 +571,7 @@ fn init_vcs(path: &Path, vcs: VersionControl, config: &Config) -> CargoResult<()
543571
fn mk(config: &Config, opts: &MkOptions<'_>) -> CargoResult<()> {
544572
let path = opts.path;
545573
let name = opts.name;
546-
let cfg = global_config(config)?;
574+
let cfg = config.get::<CargoNewConfig>("cargo-new")?;
547575

548576
// Using the push method with two arguments ensures that the entries for
549577
// both `ignore` and `hgignore` are in sync.
@@ -752,30 +780,3 @@ fn discover_author() -> CargoResult<(String, Option<String>)> {
752780

753781
Ok((name, email))
754782
}
755-
756-
fn global_config(config: &Config) -> CargoResult<CargoNewConfig> {
757-
let name = config.get_string("cargo-new.name")?.map(|s| s.val);
758-
let email = config.get_string("cargo-new.email")?.map(|s| s.val);
759-
let vcs = config.get_string("cargo-new.vcs")?;
760-
761-
let vcs = match vcs.as_ref().map(|p| (&p.val[..], &p.definition)) {
762-
Some(("git", _)) => Some(VersionControl::Git),
763-
Some(("hg", _)) => Some(VersionControl::Hg),
764-
Some(("pijul", _)) => Some(VersionControl::Pijul),
765-
Some(("none", _)) => Some(VersionControl::NoVcs),
766-
Some((s, p)) => {
767-
return Err(internal(format!(
768-
"invalid configuration for key \
769-
`cargo-new.vcs`, unknown vcs `{}` \
770-
(found in {})",
771-
s, p
772-
)));
773-
}
774-
None => None,
775-
};
776-
Ok(CargoNewConfig {
777-
name,
778-
email,
779-
version_control: vcs,
780-
})
781-
}

0 commit comments

Comments
 (0)