pathbuf-ext 0.1.0

Extends PathBuf to handle `replace` and `contains` string methods
Documentation
// Extend the PathBuf type with a replace method

use std::path::{Path, PathBuf};

pub trait PathExt {
    fn replace<T: AsRef<str>>(&self, old: T, new: T) -> PathBuf;
    fn contains<T: AsRef<str>>(&self, path: T) -> bool;
}

impl PathExt for Path {
    fn replace<T: AsRef<str>>(&self, old: T, new: T) -> PathBuf {
        let mut path = self.to_str().unwrap().to_string();

        let new2 = new.as_ref().to_string().replace("\\", "/");
        let old2 = old.as_ref().to_string().replace("\\", "/");

        let new3 = new.as_ref().to_string().replace("/", "\\");
        let old3 = old.as_ref().to_string().replace("/", "\\");

        if path.contains(&old2) {
            path = path.replace(&old2, &new2);
        } else if path.contains(&old3) {
            path = path.replace(&old3, &new3);
        }

        PathBuf::from(path)
    }

    fn contains<T: AsRef<str>>(&self, s: T) -> bool {
        let path = self.to_str().unwrap().to_string();
        
        let s2 = s.as_ref().to_string().replace("\\", "/");
        let s3 = s.as_ref().to_string().replace("/", "\\");

        path.contains(&s2) || path.contains(&s3) // || path.contains(s)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_replace() {
        let path = Path::new("C:\\Users\\user\\Desktop\\test.txt");
        let path = path.replace("C:\\Users\\user\\Desktop", "C:\\Users\\user\\Documents");
        assert_eq!(path, PathBuf::from("C:\\Users\\user\\Documents\\test.txt"));


        // Linux
        let path = Path::new("/home/user/Desktop/test.txt");
        let path = path.replace("/home/user/Desktop", "/home/user/Documents");
        assert_eq!(path, PathBuf::from("/home/user/Documents/test.txt"));

        // Mixed
        let path = Path::new("C:\\Users\\user\\Desktop\\test.txt");
        let path = path.replace("user/Desktop", "user/Documents");
        assert_eq!(path, PathBuf::from("C:\\Users\\user\\Documents\\test.txt"));
    }

    #[test]
    fn test_contains() {
        let path = Path::new("C:\\Users\\user\\Desktop\\test.txt");
        assert!(path.contains("Desktop"));
        assert!(!path.contains("Documents"));
        
        // Windows
        assert!(path.contains("user\\Desktop"));
        assert!(!path.contains("user\\Documents"));

        // Linux
        assert!(path.contains("user/Desktop"));
        assert!(!path.contains("user/Documents"));

    }

}

/*
use std::path::{Path, PathBuf};

pub trait PathExt {
    fn replace<T: ToString>(&self, old: T, new: T) -> PathBuf;
    fn contains<T: ToString>(&self, path: T) -> bool;
}

impl PathExt for Path {
    fn replace<T: ToString>(&self, old: T, new: T) -> PathBuf {
        let mut path = self.to_str().unwrap().to_string();

        let new = Path::from(new.to_string()).to_str().unwrap();
        let old = Path::from(old.to_string()).to_str().unwrap();

        path = path.replace(old, new);
        PathBuf::from(path)
    }

    fn contains<T: ToString>(&self, s: T) -> bool {
        let path = self.to_str().unwrap().to_string();

        let s = Path::from(s.to_string()).to_str().unwrap();

        path.contains(s)

    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_replace() {
        let path = Path::new("C:\\Users\\user\\Desktop\\test.txt");
        let path = path.replace("C:\\Users\\user\\Desktop", "C:\\Users\\user\\Documents");
        assert_eq!(path, PathBuf::from("C:\\Users\\user\\Documents\\test.txt"));
    }

    #[test]
    fn test_contains() {
        let path = Path::new("C:\\Users\\user\\Desktop\\test.txt");
        assert!(path.contains("Desktop"));
        assert!(!path.contains("Documents"));
    }
}
*/