tbl_core/filesystem/
manipulate.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use crate::TblError;
use std::path::{Component, Path, PathBuf};

/// get common prefix of paths
pub fn get_common_prefix(paths: &[PathBuf]) -> Result<PathBuf, TblError> {
    if paths.is_empty() {
        return Err(TblError::InputError("no paths given".to_string()));
    }

    let mut components_iter = paths.iter().map(|p| p.components());
    let mut common_components: Vec<Component<'_>> = components_iter
        .next()
        .ok_or(TblError::Error(
            "cannot parse common path components".to_string(),
        ))?
        .collect();

    for components in components_iter {
        common_components = common_components
            .iter()
            .zip(components)
            .take_while(|(a, b)| a == &b)
            .map(|(a, _)| *a)
            .collect();
    }

    Ok(common_components.iter().collect())
}

/// convert file path to new input
pub fn convert_file_path(
    input: &Path,
    output_dir: &Option<PathBuf>,
    file_prefix: &Option<String>,
    file_postfix: &Option<String>,
) -> Result<PathBuf, TblError> {
    // change output directory
    let output = match output_dir.as_ref() {
        Some(output_dir) => {
            let file_name = input
                .file_name()
                .ok_or_else(|| TblError::Error("Invalid input path".to_string()))?;
            output_dir.join(file_name)
        }
        None => input.to_path_buf(),
    };

    if file_prefix.is_some() || file_postfix.is_some() {
        let stem = output
            .file_stem()
            .ok_or_else(|| TblError::Error("Invalid output path".to_string()))?;
        let extension = output.extension();

        let new_filename = format!(
            "{}{}{}{}",
            file_prefix.as_deref().unwrap_or(""),
            stem.to_string_lossy(),
            file_postfix.as_deref().unwrap_or(""),
            extension.map_or_else(String::new, |ext| format!(".{}", ext.to_string_lossy()))
        );

        Ok(output.with_file_name(new_filename))
    } else {
        Ok(output)
    }
}