1use spinners::{Spinner, Spinners};
2use std::process::Command;
3
4pub struct OcrMyPdf {
5 args: Vec<String>,
6 input_path: String,
7 output_path: String,
8}
9
10impl OcrMyPdf {
11 pub fn new(
12 args: Option<Vec<String>>,
13 input_path: Option<String>,
14 output_path: Option<String>,
15 ) -> Self {
16 let args = args.unwrap_or(vec![]);
17 let input_path = input_path.unwrap_or(String::new());
18 let output_path = output_path.unwrap_or(String::new());
19 OcrMyPdf {
20 args,
21 input_path,
22 output_path,
23 }
24 }
25}
26
27pub trait Ocr {
28 fn execute(&mut self);
29 fn set_args(&mut self, args: Vec<String>) -> &mut Self;
30 fn set_input_path(&mut self, path: String) -> &mut Self;
31 fn set_output_path(&mut self, path: String) -> &mut Self;
32}
33
34impl Ocr for OcrMyPdf {
35 fn execute(&mut self) {
36 let _ = execute_ocr(&self.args, &self.input_path, &self.output_path);
37 }
38
39 fn set_args(&mut self, args: Vec<String>) -> &mut Self {
40 self.args = args;
41 self
42 }
43
44 fn set_input_path(&mut self, input_path: String) -> &mut Self {
45 self.input_path = input_path;
46 self
47 }
48
49 fn set_output_path(&mut self, output_path: String) -> &mut Self {
50 self.output_path = output_path;
51 self
52 }
53}
54
55fn execute_ocr(
56 args: &Vec<String>,
57 input_path: &String,
58 output_path: &String,
59) -> Result<(), Box<dyn std::error::Error>> {
60 let mut cmd = Command::new("ocrmypdf");
61 cmd.arg(input_path).arg(output_path).args(args);
62
63 let mut spinner = Spinner::new(Spinners::Runner, "Running OCR...".into());
64 let output = cmd.output().expect("Failed to execute ocrmypdf");
65
66 if output.status.success() {
67 spinner.stop_with_symbol("✔");
68 } else {
69 spinner.stop_with_message(format!(
70 "✘ Failed to run ocrmypdf with error: {}",
71 String::from_utf8_lossy(&output.stderr)
72 ));
73 }
74
75 Ok(())
76}