1pub mod git;
2pub mod hg;
3pub mod darcs;
4pub mod pijul;
5
6use std::ffi::OsStr;
7use std::fmt::Display;
8use std::path::Path;
9use std::str::FromStr;
10use util::StrSkip;
11
12
13#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
14pub enum Vcs {
15 Git,
16 Hg,
17 Darcs,
18 Pijul,
19}
20
21impl Vcs {
22 pub fn do_init<P: AsRef<Path>>(self, path: P) -> ::Result<()> {
23 match self {
24 Vcs::Git => git::init(path),
25 Vcs::Hg => hg::init(path),
26 Vcs::Darcs => darcs::initialize(path),
27 Vcs::Pijul => pijul::init(path),
28 }
29 }
30
31 pub fn do_clone<P, U, I, S>(self, path: P, url: U, args: I) -> ::Result<()>
32 where
33 P: AsRef<Path>,
34 U: AsRef<str>,
35 I: IntoIterator<Item = S>,
36 S: AsRef<OsStr> + Display,
37 {
38 match self {
39 Vcs::Git => git::clone(url, path, args),
40 Vcs::Hg => hg::clone(url, path, args),
41 Vcs::Darcs => darcs::clone(url, path, args),
42 Vcs::Pijul => pijul::clone(url, path, args),
43 }
44 }
45
46 pub fn get_remote_url<P: AsRef<Path>>(self, path: P) -> ::Result<Option<String>> {
47 match self {
48 Vcs::Git => git::get_remote_url(path),
49 Vcs::Hg => hg::get_remote_url(path),
50 _ => Err("This VCS has not supported yet".to_owned().into()),
51 }
52 }
53}
54
55pub fn detect_from_path<P: AsRef<Path>>(path: P) -> Option<Vcs> {
56 [".git", ".hg", "_darcs", ".pijul"]
57 .into_iter()
58 .find(|vcs| path.as_ref().join(vcs).exists())
59 .and_then(|s| s.skip(1).parse().ok())
60}
61
62impl FromStr for Vcs {
63 type Err = String;
64 fn from_str(s: &str) -> ::std::result::Result<Vcs, String> {
65 match s {
66 "git" => Ok(Vcs::Git),
67 "hg" => Ok(Vcs::Hg),
68 "darcs" => Ok(Vcs::Darcs),
69 "pijul" => Ok(Vcs::Pijul),
70 s => Err(format!("{} is invalid string", s)),
71 }
72 }
73}