use std::ffi::OsString;
use std::fmt;
use std::path::{Path, PathBuf};
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct RemoteLocation {
pub host: OsString,
pub path: PathBuf,
}
impl RemoteLocation {
pub fn new(s: &str) -> Result<RemoteLocation, ()> {
let mut split = s.split(':');
let host = match split.next() {
None | Some("") => return Err(()),
Some(h) => h,
};
let path = Path::new(try!(split.next().ok_or(()))).to_path_buf();
if split.next().is_some() {
return Err(());
}
Ok(RemoteLocation {
host: host.into(),
path: path,
})
}
}
impl fmt::Display for RemoteLocation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f,
"{}:{}",
self.host.as_os_str().to_str().unwrap(),
self.path.display())
}
}
#[cfg(test)]
mod tests {
use std::ffi::OsString;
use std::path::PathBuf;
use super::RemoteLocation;
#[test]
fn empty_string() {
assert!(RemoteLocation::new("").is_err());
}
#[test]
fn home() {
assert!(RemoteLocation::new("/home/user").is_err());
}
#[test]
fn root() {
assert!(RemoteLocation::new("/").is_err());
}
#[test]
fn path_without_host() {
assert!(RemoteLocation::new(":/").is_err());
}
#[test]
fn host_without_path() {
let RemoteLocation { host, path } = RemoteLocation::new("server:").unwrap();
assert_eq!(host, OsString::from("server"));
assert_eq!(path, PathBuf::from(""));
}
#[test]
fn host_with_path() {
let RemoteLocation { host, path } = RemoteLocation::new("server:/home/user").unwrap();
assert_eq!(host, OsString::from("server"));
assert_eq!(path, PathBuf::from("/home/user/"));
}
}