Simplify read_file
This commit is contained in:
parent
c4342cb073
commit
6e3b64d8c5
3 changed files with 12 additions and 45 deletions
|
|
@ -2,7 +2,7 @@ use std::{error::Error, fmt};
|
|||
|
||||
use crate::colors::{BitDepth, ColorType};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum PngError {
|
||||
APNGOutOfOrder,
|
||||
|
|
@ -15,7 +15,9 @@ pub enum PngError {
|
|||
InvalidData,
|
||||
InvalidDepthForType(BitDepth, ColorType),
|
||||
NotPNG,
|
||||
ReadFailed(String, std::io::Error),
|
||||
TruncatedData,
|
||||
WriteFailed(String, std::io::Error),
|
||||
Other(Box<str>),
|
||||
}
|
||||
|
||||
|
|
@ -47,9 +49,11 @@ impl fmt::Display for PngError {
|
|||
write!(f, "Invalid bit depth {d} for color type {c}")
|
||||
}
|
||||
PngError::NotPNG => f.write_str("Invalid header detected; Not a PNG file"),
|
||||
PngError::ReadFailed(ref s, ref e) => write!(f, "Failed to read from {s}: {e}"),
|
||||
PngError::TruncatedData => {
|
||||
f.write_str("Missing data in the file; the file is truncated")
|
||||
}
|
||||
PngError::WriteFailed(ref s, ref e) => write!(f, "Failed to write to {s}: {e}"),
|
||||
PngError::Other(ref s) => f.write_str(s),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
21
src/lib.rs
21
src/lib.rs
|
|
@ -221,7 +221,7 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<(
|
|||
let mut data = Vec::new();
|
||||
stdin()
|
||||
.read_to_end(&mut data)
|
||||
.map_err(|e| PngError::new(&format!("Error reading stdin: {e}")))?;
|
||||
.map_err(|e| PngError::ReadFailed("stdin".into(), e))?;
|
||||
data
|
||||
}
|
||||
};
|
||||
|
|
@ -270,20 +270,15 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<(
|
|||
let mut buffer = BufWriter::new(stdout());
|
||||
buffer
|
||||
.write_all(&optimized_output)
|
||||
.map_err(|e| PngError::new(&format!("Unable to write to stdout: {e}")))?;
|
||||
.map_err(|e| PngError::WriteFailed("stdout".into(), e))?;
|
||||
}
|
||||
(OutFile::Path { path, .. }, _) => {
|
||||
let output_path = path
|
||||
.as_ref()
|
||||
.map(|p| p.as_path())
|
||||
.unwrap_or_else(|| input.path().unwrap());
|
||||
let out_file = File::create(output_path).map_err(|err| {
|
||||
PngError::new(&format!(
|
||||
"Unable to write to file {}: {}",
|
||||
output_path.display(),
|
||||
err
|
||||
))
|
||||
})?;
|
||||
let out_file = File::create(output_path)
|
||||
.map_err(|err| PngError::WriteFailed(output_path.display().to_string(), err))?;
|
||||
if let Some(metadata_input) = &opt_metadata_preserved {
|
||||
copy_permissions(metadata_input, &out_file)?;
|
||||
}
|
||||
|
|
@ -293,13 +288,7 @@ pub fn optimize(input: &InFile, output: &OutFile, opts: &Options) -> PngResult<(
|
|||
.write_all(&optimized_output)
|
||||
// flush BufWriter so IO errors don't get swallowed silently on close() by drop!
|
||||
.and_then(|()| buffer.flush())
|
||||
.map_err(|e| {
|
||||
PngError::new(&format!(
|
||||
"Unable to write to {}: {}",
|
||||
output_path.display(),
|
||||
e
|
||||
))
|
||||
})?;
|
||||
.map_err(|e| PngError::WriteFailed(output_path.display().to_string(), e))?;
|
||||
// force drop and thereby closing of file handle before modifying any timestamp
|
||||
std::mem::drop(buffer);
|
||||
if let Some(metadata_input) = &opt_metadata_preserved {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,4 @@
|
|||
use std::{
|
||||
fs::File,
|
||||
io::{BufReader, Read, Write},
|
||||
path::Path,
|
||||
sync::Arc,
|
||||
};
|
||||
use std::{fs, io::Write, path::Path, sync::Arc};
|
||||
|
||||
use bitvec::bitarr;
|
||||
use libdeflater::{CompressionLvl, Compressor};
|
||||
|
|
@ -62,28 +57,7 @@ impl PngData {
|
|||
}
|
||||
|
||||
pub fn read_file(filepath: &Path) -> Result<Vec<u8>, PngError> {
|
||||
let file = match File::open(filepath) {
|
||||
Ok(f) => f,
|
||||
Err(_) => return Err(PngError::new("Failed to open file for reading")),
|
||||
};
|
||||
let file_len = file.metadata().map(|m| m.len() as usize).unwrap_or(0);
|
||||
let mut reader = BufReader::new(file);
|
||||
// Check file for PNG header
|
||||
let mut header = [0; 8];
|
||||
if reader.read_exact(&mut header).is_err() {
|
||||
return Err(PngError::new("Not a PNG file: too small"));
|
||||
}
|
||||
if !file_header_is_valid(&header) {
|
||||
return Err(PngError::new("Invalid PNG header detected"));
|
||||
}
|
||||
// Read raw png data into memory
|
||||
let mut byte_data: Vec<u8> = Vec::with_capacity(file_len);
|
||||
byte_data.extend_from_slice(&header);
|
||||
match reader.read_to_end(&mut byte_data) {
|
||||
Ok(_) => (),
|
||||
Err(_) => return Err(PngError::new("Failed to read from file")),
|
||||
}
|
||||
Ok(byte_data)
|
||||
fs::read(filepath).map_err(|e| PngError::ReadFailed(filepath.display().to_string(), e))
|
||||
}
|
||||
|
||||
/// Create a new `PngData` struct by reading a slice
|
||||
|
|
|
|||
Loading…
Reference in a new issue