serde_hkx_features/convert/
rayon.rs1use super::{OutFormat, get_output_path, get_supported_files, process_serde};
4use crate::{
5 error::{FailedConvertFilesSnafu, Result},
6 fs::write_sync,
7 progress::ProgressHandler,
8};
9use rayon::prelude::*;
10use std::{
11 fs,
12 io::{self},
13 path::{Path, PathBuf},
14};
15
16pub fn convert_progress<I, O, P>(
24 input: I,
25 output: Option<O>,
26 format: OutFormat,
27 progress: P,
28) -> Result<()>
29where
30 I: AsRef<Path>,
31 O: AsRef<Path> + Sync,
32 P: ProgressHandler + Sync,
33{
34 let input = input.as_ref();
35 if input.is_dir() {
36 convert_dir(input, output, format, progress)?;
37 } else if input.is_file() {
38 convert_file(input, output, format)?;
39 } else {
40 Err(io::Error::new(
41 io::ErrorKind::NotFound,
42 format!("The path does not exist: {}", input.display()),
43 ))?;
44 }
45
46 Ok(())
47}
48
49pub fn convert_dir<I, O, P>(
57 input_dir: I,
58 output_dir: Option<O>,
59 format: OutFormat,
60 mut progress: P,
61) -> Result<()>
62where
63 I: AsRef<Path>,
64 O: AsRef<Path> + Sync,
65 P: ProgressHandler + Sync,
66{
67 let input_dir = input_dir.as_ref();
68 let files: Vec<PathBuf> = get_supported_files(input_dir);
69
70 if files.is_empty() {
71 progress.on_empty();
72 return Ok(());
73 }
74
75 let total_files = files.len();
76 progress.on_set_total(total_files);
77
78 let err_paths: Vec<PathBuf> = files
79 .into_par_iter()
80 .filter_map(|input| {
81 progress.on_processing_path(&input);
82
83 let output = get_output_path(input_dir, &input, &output_dir, format);
84 let res = convert_file(&input, output, format);
85 progress.inc(1);
86
87 if matches!(res, Ok(())) {
88 progress.success_inc(1);
89 None
90 } else {
91 progress.failure_inc(1);
92 Some(input)
93 }
94 })
95 .collect();
96
97 progress.on_finish();
98
99 if err_paths.is_empty() {
100 Ok(())
101 } else {
102 FailedConvertFilesSnafu {
103 path: input_dir.to_path_buf(),
104 total_files,
105 err_paths,
106 }
107 .fail()
108 }
109}
110
111pub fn convert_file<I, O>(input: I, output: Option<O>, format: OutFormat) -> Result<()>
119where
120 I: AsRef<Path>,
121 O: AsRef<Path>,
122{
123 let input = input.as_ref();
124 let in_bytes = fs::read(input)?;
125 let out_bytes = process_serde(&in_bytes, input, format)?;
126
127 Ok(write_sync(input, output, format.as_extension(), out_bytes)?)
128}