#![deny(missing_docs)]
#![deny(rustdoc::broken_intra_doc_links)]
pub use slug_preserve::{CaseMode, SlugOpts};
mod error;
pub use error::FrenError;
mod opts;
pub use opts::{ConflictPolicy, PlanOpts, RenameOpts};
mod plan_types;
pub use plan_types::{DateKind, DetectedDate, ItemKind, RenamePlan};
mod report;
pub use report::ExecutionReport;
mod date;
mod execute;
mod log;
mod merge;
mod plan;
mod slugify;
pub use execute::{
execute, execute_with_log, execute_with_progress, NullProgressSink, ProgressSink,
};
pub use log::{JsonlLogSink, LogRecord, LogSink, NullLogSink};
pub use merge::{merge_directories, unique_file_name, MergeMove, MergeReport};
pub use plan::{plan, plan_with_year, sort_bottom_up};
pub use slugify::{slugify_camel_iso, slugify_camel_iso_with_year};
use std::path::Path;
pub fn rename(
roots: &[&Path],
opts: &RenameOpts,
) -> Result<(Vec<RenamePlan>, ExecutionReport), FrenError> {
let plans = plan(roots, &opts.slugify, &opts.plan)?;
let report = if opts.apply {
execute(&plans)?
} else {
ExecutionReport {
applied: 0,
skipped: 0,
errors: Vec::new(),
batch_id: plans
.first()
.map(|p| p.batch_id)
.unwrap_or_else(uuid::Uuid::nil),
log_path: None,
}
};
Ok((plans, report))
}
#[must_use]
pub fn slugify_str(input: &str, opts: &SlugOpts) -> String {
slug_preserve::slugify(input, opts)
}