1pub mod jpeg;
4pub mod png;
5use jpeg::JpegScrubber;
6use png::PngScrubber;
7use thiserror::Error;
8
9#[derive(Error, Debug)]
11pub enum ScrubError {
12 #[error("Unsupported file type: {0}")]
13 UnsupportedFileType(String),
14
15 #[error("File parsing failed: {0}")]
16 ParsingError(String),
17
18 #[error("I/O error: {0}")]
19 IoError(#[from] std::io::Error),
20
21 #[error("An unknown error occurred")]
22 Unknown,
23}
24
25#[derive(Debug, Clone, PartialEq, Eq)]
27pub struct MetadataEntry {
28 pub key: String,
29 pub value: String,
30 pub category: String, }
32
33#[derive(Debug)]
35pub struct ScrubResult {
36 pub cleaned_file_bytes: Vec<u8>,
38 pub metadata_removed: Vec<MetadataEntry>,
40}
41
42pub trait Scrubber {
45 fn new(file_bytes: Vec<u8>) -> Result<Self, ScrubError>
48 where
49 Self: Sized;
50
51 fn view_metadata(&self) -> Result<Vec<MetadataEntry>, ScrubError>;
53
54 fn scrub(&self) -> Result<ScrubResult, ScrubError>;
56}
57
58pub fn scrubber_for_file(file_bytes: Vec<u8>) -> Result<Box<dyn Scrubber>, ScrubError> {
61 if file_bytes.len() > 8 && file_bytes[0..8] == [137, 80, 78, 71, 13, 10, 26, 10] {
63 let scrubber = PngScrubber::new(file_bytes)?;
64 return Ok(Box::new(scrubber));
65 }
66
67 if file_bytes.len() > 2 && file_bytes[0..2] == [0xFF, 0xD8] {
69 let scrubber = JpegScrubber::new(file_bytes)?;
70 return Ok(Box::new(scrubber));
71 }
72
73 Err(ScrubError::UnsupportedFileType(
74 "Could not determine file type.".to_string(),
75 ))
76}