use std::fmt;
use std::path::Path;
pub mod config;
pub mod report;
pub(crate) mod fuzzy;
pub(crate) mod group;
pub(crate) mod index;
pub(crate) mod locale;
pub(crate) mod normalize;
pub(crate) mod pipeline;
pub(crate) mod po;
pub(crate) mod walk;
#[cfg(feature = "cli")]
pub mod cli;
pub use config::Config;
pub use group::CandidateGroup;
pub use index::{Cell, KeyId};
pub use pipeline::{PipelineError, PipelineEvent, ProgressSink, Report, Skip};
pub use po::PoError;
pub use walk::WalkError;
#[derive(Debug)]
pub enum Error {
Discover(WalkError),
NoFiles,
Pipeline(PipelineError),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Discover(error) => write!(f, "{error}"),
Self::NoFiles => write!(f, "no .po files found"),
Self::Pipeline(error) => write!(f, "{error}"),
}
}
}
impl std::error::Error for Error {}
pub fn scan(root: &Path, config: &Config) -> Result<Report, Error> {
scan_with(root, config, &mut ())
}
pub fn scan_with<S>(root: &Path, config: &Config, sink: &mut S) -> Result<Report, Error>
where
S: ProgressSink + ?Sized,
{
let mut config = config.clone();
config.scan.roots = vec![root.to_path_buf()];
let files = walk::discover_po_files(&config.scan).map_err(Error::Discover)?;
if files.is_empty() {
return Err(Error::NoFiles);
}
pipeline::run(&files, po::parse_po, &config, sink).map_err(Error::Pipeline)
}