finish error handling

This commit is contained in:
132nd-Professor
2022-08-12 16:39:38 +02:00
parent f87a3c9e06
commit d7db52fc2d
4 changed files with 53 additions and 45 deletions
+11 -11
View File
@@ -19,20 +19,20 @@ fn main_inner() -> Result<(), Box<dyn std::error::Error>> {
let (input_filename, is_zip) = reader::find_input_file()?; let (input_filename, is_zip) = reader::find_input_file()?;
println!("Processing {}", input_filename); println!("Processing {}", input_filename);
let lines = reader::read_data(&input_filename, is_zip)?; let lines = reader::read_data(&input_filename, is_zip)?;
let (header, body) = processor::split_into_header_and_body(&lines); let (header, body) = processor::split_into_header_and_body(&lines)?;
let coalition_per_line = processor::divide_body_by_coalition(body); let coalition_per_line = processor::divide_body_by_coalition(body)?;
let mut blue_writer = writer::create_writer(is_zip, &input_filename); let mut blue_writer = writer::create_writer(is_zip, &input_filename)?;
blue_writer.write_strings(header); blue_writer.write_strings(header)?;
blue_writer.write_for_coalition(body, &coalition_per_line, Coalition::Blue); blue_writer.write_for_coalition(body, &coalition_per_line, Coalition::Blue)?;
let mut red_writer = writer::create_writer(is_zip, &input_filename); let mut red_writer = writer::create_writer(is_zip, &input_filename)?;
red_writer.write_strings(header); red_writer.write_strings(header)?;
red_writer.write_for_coalition(body, &coalition_per_line, Coalition::Red); red_writer.write_for_coalition(body, &coalition_per_line, Coalition::Red)?;
let mut purple_writer = writer::create_writer(is_zip, &input_filename); let mut purple_writer = writer::create_writer(is_zip, &input_filename)?;
purple_writer.write_strings(header); purple_writer.write_strings(header)?;
purple_writer.write_for_coalition(body, &coalition_per_line, Coalition::Purple); purple_writer.write_for_coalition(body, &coalition_per_line, Coalition::Purple)?;
Ok(()) Ok(())
} }
+3 -3
View File
@@ -5,7 +5,7 @@ use std::hash::Hash;
use crate::constants::{COMMENT, MINUS}; use crate::constants::{COMMENT, MINUS};
use crate::tacview::{Coalition, CoalitionIDs}; use crate::tacview::{Coalition, CoalitionIDs};
pub fn split_into_header_and_body<S, E>(lines: &[S]) -> Result<(&[S], &[S]), ProcessingError> pub fn split_into_header_and_body<S>(lines: &[S]) -> Result<(&[S], &[S]), ProcessingError>
where where
S: AsRef<str>, S: AsRef<str>,
{ {
@@ -15,7 +15,7 @@ where
.as_ref() .as_ref()
.chars() .chars()
.next() .next()
.ok_or(ProcessingError::LineIsEmptyError)? .ok_or(ProcessingError::CannotSplitIntoHeaderAndBody)?
== COMMENT == COMMENT
{ {
break; break;
@@ -147,7 +147,7 @@ impl LineType {
} }
#[derive(Debug)] #[derive(Debug)]
enum ProcessingError { pub enum ProcessingError {
LineIsEmptyError, LineIsEmptyError,
UnknownLineType, UnknownLineType,
CannotSplitIntoHeaderAndBody, CannotSplitIntoHeaderAndBody,
+5 -5
View File
@@ -35,13 +35,13 @@ fn read_zip(buf: BufReader<File>) -> Result<Vec<String>, Error> {
let mut archive = zip::ZipArchive::new(buf)?; let mut archive = zip::ZipArchive::new(buf)?;
let inner_file = archive.by_index(0)?; let inner_file = archive.by_index(0)?;
let inner_buf = BufReader::new(inner_file); let inner_buf = BufReader::new(inner_file);
Ok(read_txt(inner_buf)?) read_txt(inner_buf)
} }
fn read_txt(buf: impl BufRead) -> Result<Vec<String>, Error> { fn read_txt(buf: impl BufRead) -> Result<Vec<String>, Error> {
let lines: Vec<String> = buf let mut lines = vec![];
.lines() for line in buf.lines() {
.map(|l| l.expect("Could not read from the file")) lines.push(line?);
.collect(); }
Ok(lines) Ok(lines)
} }
+34 -26
View File
@@ -1,19 +1,20 @@
use crate::constants::{EXTENSION_TXT, EXTENSION_ZIP}; use crate::constants::{EXTENSION_TXT, EXTENSION_ZIP};
use crate::tacview::Coalition; use crate::tacview::Coalition;
use std::error::Error as ErrTrait;
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::{Error, Write};
use zip::write::FileOptions; use zip::write::FileOptions;
use zip::ZipWriter; use zip::ZipWriter;
pub fn create_writer(is_zip: bool, filename: &str) -> Box<dyn Write> { pub fn create_writer(is_zip: bool, filename: &str) -> Result<Box<dyn Write>, Box<dyn ErrTrait>> {
let base_name = remove_extension(filename, is_zip); let base_name = remove_extension(filename, is_zip);
if is_zip { if is_zip {
Box::new(create_zipwriter( Ok(Box::new(create_zipwriter(
&format!("{base_name}{EXTENSION_ZIP}"), &format!("{base_name}{EXTENSION_ZIP}"),
&format!("{base_name}{EXTENSION_TXT}"), &format!("{base_name}{EXTENSION_TXT}"),
)) )?))
} else { } else {
Box::new(create_textwriter(base_name)) Ok(Box::new(create_textwriter(base_name)?))
} }
} }
@@ -25,45 +26,45 @@ fn remove_extension(filename: &str, is_zip: bool) -> &str {
} }
} }
fn create_textwriter(filename: &str) -> File { fn create_textwriter(filename: &str) -> Result<File, Error> {
File::create(filename).unwrap() File::create(filename)
} }
fn create_zipwriter(outer_name: &str, inner_name: &str) -> ZipWriter<File> { fn create_zipwriter(outer_name: &str, inner_name: &str) -> Result<ZipWriter<File>, Error> {
let mut writer = ZipWriter::new(create_textwriter(outer_name)); let mut writer = ZipWriter::new(create_textwriter(outer_name)?);
writer writer.start_file(
.start_file( inner_name,
inner_name, FileOptions::default().compression_method(zip::CompressionMethod::Deflated),
FileOptions::default().compression_method(zip::CompressionMethod::Deflated), )?;
) Ok(writer)
.unwrap();
writer
} }
pub trait StringWriter { pub trait StringWriter {
fn write_line<S: AsRef<str>>(&mut self, line: &S); fn write_line<S: AsRef<str>>(&mut self, line: &S) -> Result<(), Error>;
fn write_strings<S: AsRef<str>>(&mut self, lines: &[S]); fn write_strings<S: AsRef<str>>(&mut self, lines: &[S]) -> Result<(), Error>;
fn write_for_coalition<S: AsRef<str>>( fn write_for_coalition<S: AsRef<str>>(
&mut self, &mut self,
lines: &[S], lines: &[S],
coalition_per_line: &[Coalition], coalition_per_line: &[Coalition],
coalition: Coalition, coalition: Coalition,
); ) -> Result<(), Box<dyn std::error::Error>>;
} }
impl<T> StringWriter for T impl<T> StringWriter for T
where where
T: Write, T: Write,
{ {
fn write_line<S: AsRef<str>>(&mut self, line: &S) { fn write_line<S: AsRef<str>>(&mut self, line: &S) -> Result<(), Error> {
writeln!(self, "{}", line.as_ref()).unwrap(); writeln!(self, "{}", line.as_ref())
} }
fn write_strings<S: AsRef<str>>(&mut self, lines: &[S]) { fn write_strings<S: AsRef<str>>(&mut self, lines: &[S]) -> Result<(), Error> {
for line in lines { for line in lines {
self.write_line(line); self.write_line(line)?;
} }
Ok(())
} }
fn write_for_coalition<S: AsRef<str>>( fn write_for_coalition<S: AsRef<str>>(
@@ -71,12 +72,19 @@ where
lines: &[S], lines: &[S],
coalition_per_line: &[Coalition], coalition_per_line: &[Coalition],
coalition: Coalition, coalition: Coalition,
) { ) -> Result<(), Box<dyn std::error::Error>> {
assert_eq!(lines.len(), coalition_per_line.len()); assert_eq!(lines.len(), coalition_per_line.len());
lines
let iter = lines
.iter() .iter()
.zip(coalition_per_line) .zip(coalition_per_line)
.filter(|(_, c)| **c == coalition || **c == Coalition::All) .filter(|(_, c)| **c == coalition || **c == Coalition::All)
.for_each(|(l, _)| self.write_line(l)); .map(|(l, _)| l);
for line in iter {
self.write_line(line)?;
}
Ok(())
} }
} }