1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
#![deny(missing_debug_implementations)] pub mod aggregate_report; use std::fs::{File, read_dir}; use std::io::BufReader; use std::path::Path; use serde_xml_rs::from_reader; use libflate::gzip; use zip; use std::io::Read; pub fn parse(path: &Path) -> Result<aggregate_report::feedback, Box<std::error::Error>> { if path.is_dir() { panic!("{} is a directory") } let extension = path.extension(); match extension { Some(extension) => { match extension.to_str().unwrap() { "xml" => { let mut reader = get_file_reader(&path)?; return parse_reader(&mut reader); }, "gz" | "gzip" => { let reader = get_file_reader(&path)?; let mut decoder = gzip::Decoder::new(reader)?; return parse_reader(&mut decoder); }, "zip" => { let file = File::open(&path)?; let mut archive = zip::ZipArchive::new(file)?; let mut file = archive.by_index(0)?; return parse_reader(&mut file); }, _ => { let error_message = format!("Do not know how to handle {} files :-(", extension.to_str().unwrap()); return Err(error_message.into()); } } }, None => () } let file = File::open(&path)?; let mut file = BufReader::new(file); parse_reader(&mut file) } fn get_file_reader(path: &Path) -> Result<BufReader<File>, Box<std::error::Error>> { let file = File::open(&path)?; Ok(BufReader::new(file)) } fn parse_reader(reader: &mut Read) -> Result<aggregate_report::feedback, Box<std::error::Error>> { match from_reader(reader) { Ok(result) => Ok(result), Err(error) => Err(error.into()) } } pub fn parse_dir(path: &Path) -> Vec<aggregate_report::feedback> { let mut results = Vec::new(); if path.is_dir() { for entry in read_dir(path).unwrap() { let entry = entry.unwrap(); let path = entry.path(); let result = parse(&path); match result { Ok(result) => results.push(result), Err(error) => println!("could not parse: {:?} because {:?}", path, error) } } } results } #[cfg(test)] mod tests { use super::*; #[test] fn test_parse_single() { parse("dmarc.xml"); } #[test] fn test_parse_dir() { parse_dir(Path::new("./")); } }