processors_rs/
docx_processor.rs1use crate::markdown_processor::MarkdownProcessor;
2use crate::processor::{Document, DocumentProcessor, FileProcessor};
3use docx_parser::MarkdownDocument;
4use std::path::Path;
5use text_splitter::ChunkConfigError;
6
7pub struct DocxProcessor {
9 markdown_processor: MarkdownProcessor,
10}
11
12impl DocxProcessor {
13 pub fn new(chunk_size: usize, overlap: usize) -> Result<DocxProcessor, ChunkConfigError> {
14 let markdown_processor = MarkdownProcessor::new(chunk_size, overlap)?;
15 Ok(DocxProcessor { markdown_processor })
16 }
17}
18
19impl FileProcessor for DocxProcessor {
20 fn process_file(&self, path: impl AsRef<Path>) -> anyhow::Result<Document> {
21 let path = path.as_ref().to_owned();
26 let docs =
27 std::panic::catch_unwind(move || MarkdownDocument::from_file(&path)).map_err(|e| {
28 let msg = if let Some(s) = e.downcast_ref::<String>() {
29 s.clone()
30 } else if let Some(s) = e.downcast_ref::<&str>() {
31 s.to_string()
32 } else {
33 "unknown panic".to_string()
34 };
35 anyhow::anyhow!("docx_parser panicked while opening file: {}", msg)
36 })?;
37 let markdown = docs.to_markdown(false);
38 self.markdown_processor.process_document(&markdown)
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45 #[test]
46 fn test_extract_text() {
47 let txt_file = "../test_files/test.docx";
48 let processor = DocxProcessor::new(128, 0).unwrap();
49
50 let text = processor.process_file(txt_file).unwrap();
51 assert!(text
52 .chunks
53 .contains(&"This is a docx file test".to_string()));
54 }
55
56 #[test]
58 #[should_panic(
59 expected = "Error processing file: IO(Os { code: 2, kind: NotFound, message: \"No such file or directory\" })"
60 )]
61 fn test_extract_text_invalid_file_path() {
62 let invalid_file_path = "this_file_definitely_does_not_exist.docx";
63 let processor = DocxProcessor::new(128, 0).unwrap();
64 processor.process_file(invalid_file_path).unwrap();
65 }
66}