use std::fmt::{Display, Formatter};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Platform {
Linux,
Mac,
Win,
}
impl Platform {
pub fn is_target(&self) -> bool {
match self {
Platform::Linux => cfg!(target_os = "linux"),
Platform::Mac => cfg!(target_os = "macos"),
Platform::Win => cfg!(target_os = "windows"),
}
}
pub fn is_absolute_path(&self, path: &str) -> bool {
match self {
Platform::Linux | Platform::Mac => path.starts_with('/'),
Platform::Win => {
let first_fragment = match path.find(['/', '\\']) {
Some(first_fragment_len) => &path[..first_fragment_len],
None => path,
};
first_fragment.is_empty() || first_fragment.ends_with(':')
}
}
}
pub fn join_paths(&self, left: &str, right: &str) -> String {
match self {
Platform::Linux | Platform::Mac => {
let left = left.trim_end_matches('/');
let right = right.trim_start_matches('/');
format!("{left}/{right}")
}
Platform::Win => {
let left = left.trim_end_matches(['/', '\\']);
let right = right.trim_start_matches(['/', '\\']);
if left.starts_with('/') {
format!("{left}/{right}")
} else {
format!("{left}\\{right}")
}
}
}
}
}
impl Display for Platform {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
let p = match self {
Self::Linux => "Linux",
Self::Mac => "Mac",
Self::Win => "windows",
};
write!(f, "{p}")
}
}
#[cfg(test)]
mod test {
use crate::platform::Platform;
#[test]
fn test_linux() {
assert!(Platform::Linux.is_absolute_path("/home/test/filename"));
assert!(!Platform::Linux.is_absolute_path("test/filename"));
assert!(!Platform::Linux.is_absolute_path("../test/filename"));
assert_eq!(
&Platform::Linux.join_paths("/home/test/", "filename"),
"/home/test/filename"
);
assert_eq!(
&Platform::Linux.join_paths("/home/test", "filename"),
"/home/test/filename"
);
assert_eq!(
&Platform::Linux.join_paths("/home/test/", "test2/filename"),
"/home/test/test2/filename"
);
assert_eq!(
&Platform::Linux.join_paths("/home/test/", "/test2/filename"),
"/home/test/test2/filename"
);
assert_eq!(
&Platform::Linux.join_paths("/home/test", "/test2/filename"),
"/home/test/test2/filename"
);
}
#[test]
fn test_win() {
assert!(Platform::Win.is_absolute_path("/home/test/filename"));
assert!(Platform::Win.is_absolute_path(r"D:\Users\test\filename"));
assert!(Platform::Win.is_absolute_path(r"\\netshare\test\filename"));
assert!(Platform::Win.is_absolute_path(r"E:/Users/test/filename"));
assert!(!Platform::Win.is_absolute_path("../test/filename"));
assert!(!Platform::Win.is_absolute_path("test/filename"));
assert!(!Platform::Win.is_absolute_path(r"..\test\filename"));
assert!(!Platform::Win.is_absolute_path(r"test\filename"));
assert_eq!(
&Platform::Win.join_paths(r"C:\Users\test\", "filename"),
r"C:\Users\test\filename"
);
assert_eq!(
&Platform::Win.join_paths(r"C:\Users\test", r"filename"),
r"C:\Users\test\filename"
);
assert_eq!(
&Platform::Win.join_paths(r"C:\Users\test", r"test2\filename"),
r"C:\Users\test\test2\filename"
);
assert_eq!(
&Platform::Win.join_paths(r"C:\Users\test", r"\test2\filename"),
r"C:\Users\test\test2\filename"
);
assert_eq!(
&Platform::Win.join_paths(r"C:\Users\test", r"\test2\filename"),
r"C:\Users\test\test2\filename"
);
assert_eq!(
&Platform::Win.join_paths("/home/test/", "filename"),
"/home/test/filename"
);
assert_eq!(
&Platform::Win.join_paths("/home/test", "filename"),
"/home/test/filename"
);
assert_eq!(
&Platform::Win.join_paths("/home/test/", "test2/filename"),
"/home/test/test2/filename"
);
assert_eq!(
&Platform::Win.join_paths("/home/test/", "/test2/filename"),
"/home/test/test2/filename"
);
assert_eq!(
&Platform::Win.join_paths("/home/test", "/test2/filename"),
"/home/test/test2/filename"
);
}
}