1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
pub mod git;
pub mod hg;
pub mod darcs;
pub mod pijul;

use std::ffi::OsStr;
use std::fmt::Display;
use std::path::Path;
use std::str::FromStr;
use util::StrSkip;


#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum Vcs {
    Git,
    Hg,
    Darcs,
    Pijul,
}

impl Vcs {
    pub fn do_init<P: AsRef<Path>>(self, path: P) -> ::Result<()> {
        match self {
            Vcs::Git => git::init(path),
            Vcs::Hg => hg::init(path),
            Vcs::Darcs => darcs::initialize(path),
            Vcs::Pijul => pijul::init(path),
        }
    }

    pub fn do_clone<P, U, I, S>(self, path: P, url: U, args: I) -> ::Result<()>
    where
        P: AsRef<Path>,
        U: AsRef<str>,
        I: IntoIterator<Item = S>,
        S: AsRef<OsStr> + Display,
    {
        match self {
            Vcs::Git => git::clone(url, path, args),
            Vcs::Hg => hg::clone(url, path, args),
            Vcs::Darcs => darcs::clone(url, path, args),
            Vcs::Pijul => pijul::clone(url, path, args),
        }
    }

    pub fn get_remote_url<P: AsRef<Path>>(self, path: P) -> ::Result<Option<String>> {
        match self {
            Vcs::Git => git::get_remote_url(path),
            Vcs::Hg => hg::get_remote_url(path),
            _ => Err("This VCS has not supported yet".to_owned().into()),
        }
    }
}

pub fn detect_from_path<P: AsRef<Path>>(path: P) -> Option<Vcs> {
    [".git", ".hg", "_darcs", ".pijul"]
        .into_iter()
        .find(|vcs| path.as_ref().join(vcs).exists())
        .and_then(|s| s.skip(1).parse().ok())
}

impl FromStr for Vcs {
    type Err = String;
    fn from_str(s: &str) -> ::std::result::Result<Vcs, String> {
        match s {
            "git" => Ok(Vcs::Git),
            "hg" => Ok(Vcs::Hg),
            "darcs" => Ok(Vcs::Darcs),
            "pijul" => Ok(Vcs::Pijul),
            s => Err(format!("{} is invalid string", s)),
        }
    }
}