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> { vec![ Box::new(Git::new()) ] } fn read_remote(file_path: &PathBuf) -> Option { let mut file = File::open(file_path).ok()?; let mut contents = String::new(); file.read_to_string(&mut contents).ok()?; Some(contents) }