#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
#[derive(PartialEq, Eq, Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum PathType {
File,
Directory,
Invalid,
}
#[derive(PartialEq, Eq, Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Path {
path: String,
}
impl Path {
#[cfg(target_os = "windows")]
pub const SPLIT_CHAR: char = '\\';
#[cfg(not(target_os = "windows"))]
pub const SPLIT_CHAR: char = '/';
#[cfg(target_os = "windows")]
pub const NOT_SPLIT_CHAR: char = '/';
#[cfg(not(target_os = "windows"))]
pub const NOT_SPLIT_CHAR: char = '\\';
pub fn new(user_path: &str) -> Self {
let mut path = user_path.to_string();
if path.ends_with(Self::SPLIT_CHAR) {
path = path[0..path.len() - 1].to_string();
}
path = path.replace(
Self::NOT_SPLIT_CHAR.to_string().as_str(),
Self::SPLIT_CHAR.to_string().as_str(),
);
return Self {
path,
};
}
pub fn exists(&self) -> bool {
return std::path::Path::new(self.path.as_str()).exists();
}
pub fn basename(&self) -> String {
let mut segments: Vec<String> = Vec::new();
for i in self.to_string().split(Self::SPLIT_CHAR) {
segments.push(i.to_string());
}
return segments[segments.len() - 1].to_string();
}
pub fn parent_path(&self) -> Self {
return Self::new(&self.to_string().replace(&format!("{sc}{}", self.basename(), sc = Self::SPLIT_CHAR), ""));
}
pub fn path_type(&self) -> PathType {
if self.exists() == false {
return PathType::Invalid;
}
if std::path::Path::new(self.to_string().as_str()).is_file() {
return PathType::File;
}
else {
return PathType::Directory;
}
}
pub fn add(&self, extra: &Self) -> Self {
if extra.to_string().starts_with(Self::SPLIT_CHAR) == false {
return Self::new(&format!("{}/{}", self.to_string(), extra.to_string()));
}
else {
return Self::new(&format!("{}{}", self.to_string(), extra.to_string()));
}
}
pub fn add_str(&self, extra: &str) -> Self {
return self.add(&Path::new(extra));
}
}
impl ToString for Path {
fn to_string(&self) -> String {
return self.path.to_string();
}
}