1mod config;
2mod i18n;
3mod remove_xml_tags;
4
5#[cfg(feature = "cli")]
6pub mod cli;
7#[cfg(feature = "gui")]
8pub mod gui;
9
10use std::{
11 error::Error,
12 path::{self, Path, PathBuf},
13 result,
14};
15
16pub type Result<T> = result::Result<T, Box<dyn Error>>;
17
18pub use config::{
19 Config,
20 input::{Input, InputFile, InputFileType},
21 output::Output,
22 tags::Tags,
23};
24pub use i18n::{Lang, Msg};
25pub use remove_xml_tags::remove_xml_tags;
26
27#[cfg(windows)]
28const LONG_PATH_PREFIX: &str = r"\\?\";
29
30fn log_prefix_root(level: log::Level) -> &'static str {
31 use log::Level;
32 let msg = match level {
33 Level::Error => Msg::Error,
34 Level::Warn => Msg::Warning,
35 Level::Debug => Msg::Debug,
36 Level::Trace => Msg::Trace,
37 _ => return "",
38 };
39 msg.as_str()
40}
41
42fn ensure_long_path_prefix(path: impl Into<PathBuf>) -> PathBuf {
43 #[cfg(unix)]
44 {
45 path.into()
46 }
47
48 #[cfg(windows)]
49 {
50 let path = path.into();
51
52 if path
53 .as_os_str()
54 .as_encoded_bytes()
55 .starts_with(LONG_PATH_PREFIX.as_bytes())
56 {
57 return path;
58 }
59
60 let mut prf_path = std::ffi::OsString::from(LONG_PATH_PREFIX);
61 prf_path.push(path.as_os_str());
62 prf_path.into()
63 }
64}
65
66fn display<P>(path: &P) -> path::Display<'_>
68where
69 P: AsRef<Path> + ?Sized,
70{
71 let path = path.as_ref();
72
73 #[cfg(windows)]
74 {
75 let src_bytes = path.as_os_str().as_encoded_bytes();
76
77 if src_bytes.starts_with(LONG_PATH_PREFIX.as_bytes()) {
78 let display_bytes = if src_bytes.len() == 4 {
79 &[]
80 } else {
81 &src_bytes[4..]
82 };
83
84 let os_str = unsafe { std::ffi::OsStr::from_encoded_bytes_unchecked(display_bytes) };
88
89 return Path::new(os_str).display();
90 }
91 }
92
93 path.display()
94}