verethiel 0.2.0

CLI tool to verify, sort and diff i18n JSON files against a base template
use std::{path::PathBuf, process::exit};

use crate::utility::{open_file, Translation};

pub(crate) fn sort(
    base_path: PathBuf,
    source: PathBuf,
    recursive: bool,
    output: Option<PathBuf>,
    strict: bool,
) {
    if let Some(output) = &output {
        let both_dir = source.is_dir() && output.is_dir();
        let both_file = source.is_file() && output.is_file();
        if !both_file && !both_dir {
            eprintln!(
                "When using output, output and source must either be a directory or file, they can't be different"
            );
            exit(2);
        }
    }
    let base = match open_file(&base_path) {
        Ok(base) => base,
        Err(err) => {
            eprintln!("{err}");
            exit(1);
        }
    };
    if let Err(err) = if source == base_path {
        Err("Source and base should not be the same".to_string())
    } else if source.is_dir() {
        sort_directory(source, &base, output, recursive, &base_path, strict)
    } else if source.is_file() {
        sort_file(source, &base, output, strict)
    } else {
        Err("source is neither and existing file nor an existing directory".to_string())
    } {
        eprintln!("{err}");
        exit(1);
    }
}
fn sort_directory(
    path: PathBuf,
    base: &Translation,
    output: Option<PathBuf>,
    recursive: bool,
    base_path: &PathBuf,
    strict: bool,
) -> Result<(), String> {
    for entry in std::fs::read_dir(&path)
        .map_err(|_| format!("Failed to open directory '{}'", path.display()))?
    {
        let Ok(entry) = entry else {
            continue;
        };
        let new_output = output.clone().map(|path| path.join(entry.path()));
        if recursive && entry.path().is_dir() {
            sort_directory(entry.path(), base, new_output, recursive, base_path, strict)?;
        } else if entry.path().is_file() && base_path != &entry.path() {
            println!("'{}' '{}'", base_path.display(), entry.path().display());
            sort_file(entry.path(), base, new_output, strict)?;
        }
    }
    Ok(())
}
fn sort_file(
    path: PathBuf,
    base: &Translation,
    output: Option<PathBuf>,
    strict: bool,
) -> Result<(), String> {
    let output_path = output.unwrap_or_else(|| path.clone());
    let mut translation = open_file(&path)?;
    if strict {
        crate::verify::validate_file(path, base, strict)?;
    }
    translation.apply_translation_order(base)?;
    std::fs::write(output_path, translation.to_string())
        .map_err(|err| format!("Failed to write to file: {err}"))
}

#[cfg(test)]
mod tests;