use crate::{exec_cmd, Arguments, Config, MyResult};
use std::{path::PathBuf, process::Command};
#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
pub struct FileInfo {
pub dimension: Dimension,
pub is_valid: bool,
pub size: u64,
pub path: PathBuf,
}
impl FileInfo {
pub fn path_contains(&self, string: &str) -> bool {
match self.path.to_str() {
Some(p) => p.contains(string),
None => false,
}
}
pub fn update_info(&mut self, config: &Config, args: &Arguments) -> MyResult<()> {
let mut cmd = Command::new("identify");
let identify_cmd = cmd
.arg("-format")
.arg("%wx%h") .arg(&self.path);
let identify_out = exec_cmd(identify_cmd, args, "identify")?;
let sdt_output = String::from_utf8(identify_out.stdout)?;
let dimension = Dimension::new(&sdt_output);
self.dimension = dimension;
self.is_valid = self.check_validity(config);
println!("{self:?}");
Ok(())
}
fn check_validity(&self, config: &Config) -> bool {
let width = self.dimension.width;
let height = self.dimension.height;
let min = width.min(height);
min > config.dimension
}
}
pub trait FileInfoExt {
fn get_width_min(&self) -> Option<u32>;
}
impl FileInfoExt for [FileInfo] {
fn get_width_min(&self) -> Option<u32> {
self.iter().map(|file_info| file_info.dimension.width).min()
}
}
#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
pub struct Dimension {
pub width: u32,
pub height: u32,
}
impl Dimension {
pub fn new(string: &str) -> Dimension {
let (width, height) = split_str(string);
Dimension { width, height }
}
}
fn split_str(string: &str) -> (u32, u32) {
let numbers: Vec<u32> = string
.trim()
.split('x')
.flat_map(|number| number.parse::<u32>())
.collect();
if numbers.len() != 2 {
eprintln!("fn split_str()");
panic!("Error: split '{string}' for Vec<u32>");
}
let width = numbers[0];
let height = numbers[1];
if numbers.iter().any(|&n| n == 0) {
eprintln!("fn split_str()");
eprintln!("width: {width}, heigth: {height}");
panic!("width and height must be greater then zero!");
}
(width, height)
}
#[cfg(test)]
mod test_info {
#[test]
fn get_min_value_of_vec_v1() {
let values: Vec<i32> = vec![5, 6, 8, 4, 2, 7];
let min_value: Option<i32> = values.iter().min().copied();
println!("values: {values:?}");
println!("min_value: {min_value:?}");
assert_eq!(min_value, Some(2));
}
#[test]
fn get_min_value_of_vec_v2() {
let values: Vec<i32> = vec![5, 6, 8, 4, 2, 7];
let min_value: i32 = values
.iter()
.fold(i32::MAX, |arg0: i32, other: &i32| i32::min(arg0, *other));
println!("values: {values:?}");
println!("min_value: {min_value}");
assert_eq!(min_value, 2);
}
}