rialight_filesystem 1.4.0

Rialight file system module.
Documentation
use lazy_regex::{lazy_regex, Lazy, Regex};

static PATH_SEPARATOR: Lazy<Regex> = lazy_regex!(r"[/\\]");
static STARTS_WITH_PATH_SEPARATOR: Lazy<Regex> = lazy_regex!(r"^[/\\]");

pub fn relative_path(from_path: &str, to_path: &str) -> String {
    let mut r = Vec::<String>::new();

    let mut from_parts: Vec<String> = PATH_SEPARATOR.split(resolve_single_path(from_path).as_ref()).map(|s| s.to_owned()).collect();
    let mut to_parts: Vec<String> = PATH_SEPARATOR.split(resolve_single_path(to_path).as_ref()).map(|s| s.to_owned()).collect();

    let mut common_indices = Vec::<usize>::new();

    for i in 0..from_parts.len() {
        if from_parts[i] == to_parts[i] {
            common_indices.push(i);
        }
    }
    for i in common_indices.iter().rev() {
        let j = common_indices[*i];
        from_parts.remove(j);
        to_parts.remove(j);
    }
    for _i in 0..from_parts.len() {
        r.push("..".to_owned());
    }
    for s in to_parts {
        r.push(s.clone());
    }

    let r = r.join("/");
    let r = r.trim();
    if r.is_empty() { ".".to_owned() } else { r.to_owned() }
}

fn resolve_single_path(path: &str) -> String {
    let mut r = Vec::<String>::new();
    for p in PATH_SEPARATOR.split(path) {
        if p == "." {
            continue;
        } else if p == ".." {
            if !r.is_empty() {
                r.remove(r.len() - 1);
            }
        } else if !p.is_empty() {
            r.push(p.to_owned());
        }
    }
    r.join("/")
}

pub fn resolve_two_paths(path1: &str, path2: &str) -> String {
    let starts_with_slash = path1.starts_with("/");
    #[allow(unused_assignments)]
    let mut r = "".to_owned();
    if STARTS_WITH_PATH_SEPARATOR.is_match(path2) {
        r = resolve_single_path(path2);
    } else {
        let path1_resolved = resolve_single_path(path1);
        if path2.is_empty() {
            r = path1_resolved;
        }
        else {
            let paths_combination = path1_resolved + "/" + path2;
            r = resolve_single_path(paths_combination.as_ref());
        }
    }
    if starts_with_slash {
        r = "/".to_owned() + &r;
    }
    r
}