aboutsummaryrefslogtreecommitdiff
path: root/src/remote/mod.rs
blob: 19514af5ba35e8c2ed66e7b1d10c334ad30cff8c (plain)
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
mod git;

use std::fs::{create_dir_all, remove_file, write, File};
use std::io::{Error, ErrorKind::Other, Read, Result};
use std::path::PathBuf;

use git::Git;

pub trait Remote {
    fn can_handle(&self, remote: &str) -> bool;
    fn sync_up(&self, remote: &str, directory: &PathBuf) -> Result<()>;
    fn sync_down(&self, remote: &str, directory: &PathBuf) -> Result<()>;
}

pub fn add(config_directory: &PathBuf, remote_config: &PathBuf, remote: &String) -> Result<()> {
    create_dir_all(config_directory)?;
    write(remote_config, remote)?;
    Ok(())
}

pub fn remove(remote_config: &PathBuf) -> Result<()> {
    if remote_config.exists() {
        remove_file(remote_config)?
    }
    Ok(())
}

pub fn sync_up(data_directory: &PathBuf, remote_config: &PathBuf) -> Result<()> {
    let remote_address = read_remote(remote_config)
        .ok_or_else(|| Error::new(Other, "No remote is configured"))?;
    create_dir_all(data_directory)?;
    let remotes = available_remotes();
    for remote in remotes {
        if remote.can_handle(&remote_address) {
            return remote.sync_up(&remote_address, data_directory);
        }
    }
    Err(Error::new(Other, "No valid strategies found for your configured remote."))
}

pub fn sync_down(data_directory: &PathBuf, remote_config: &PathBuf) -> Result<()> {
    let remote_address = read_remote(remote_config)
        .ok_or_else(|| Error::new(Other, "No remote is configured"))?;
    create_dir_all(data_directory)?;
    let remotes = available_remotes();
    for remote in remotes {
        if remote.can_handle(&remote_address) {
            return remote.sync_down(&remote_address, data_directory);
        }
    }
    Err(Error::new(Other, "No valid strategies found for your configured remote."))
}

fn available_remotes() -> Vec<Box<dyn Remote>> {
    vec![
        Box::new(Git::new())
    ]
}

fn read_remote(file_path: &PathBuf) -> Option<String> {
    let mut file = File::open(file_path).ok()?;
    let mut contents = String::new();
    file.read_to_string(&mut contents).ok()?;
    Some(contents)
}