dimensions: rename some functions to be more idiomatic Rust
- ID
526f256- date
2026-09-24 05:02:12+00:00- author
Alex Chan <alex@alexwlchan.net>- parent
72d9323- message
dimensions: rename some functions to be more idiomatic Rust- changed files
3 files, 52 additions, 52 deletions
Changed files
src/create_thumbnail.rs (8839 → 8803)
diff --git a/src/create_thumbnail.rs b/src/create_thumbnail.rs
index 439182a..eb0d5c8 100644
--- a/src/create_thumbnail.rs
+++ b/src/create_thumbnail.rs
@@ -6,8 +6,8 @@ use image::imageops::FilterType;
use image::{DynamicImage, ImageDecoder, ImageReader};
use crate::create_parent_directory::create_parent_directory;
+use crate::dimensions::{thumbnail_dimensions, TargetDimension};
use crate::errors::ThumbnailError;
-use crate::get_thumbnail_dimensions::{get_thumbnail_dimensions, TargetDimension};
use crate::is_animated_gif::is_animated_gif;
/// Create a thumbnail for the image, and return the relative path of
@@ -26,7 +26,7 @@ pub fn create_thumbnail(
return Err(ThumbnailError::SameInputOutputPath);
}
- let (new_width, new_height) = get_thumbnail_dimensions(&path, target)?;
+ let (new_width, new_height) = thumbnail_dimensions(&path, target)?;
if is_animated_gif(path)? {
create_animated_gif_thumbnail(path, out_dir, new_width, new_height)
@@ -40,7 +40,7 @@ mod test_create_thumbnail {
use std::path::PathBuf;
use super::create_thumbnail;
- use crate::get_thumbnail_dimensions::TargetDimension;
+ use crate::dimensions::TargetDimension;
use crate::test_utils::{get_dimensions, test_dir};
#[test]
src/get_thumbnail_dimensions.rs (5123) → src/dimensions.rs (5023)
diff --git a/src/get_thumbnail_dimensions.rs b/src/dimensions.rs
similarity index 74%
rename from src/get_thumbnail_dimensions.rs
rename to src/dimensions.rs
index 003d46f..62ddf80 100644
--- a/src/get_thumbnail_dimensions.rs
+++ b/src/dimensions.rs
@@ -1,4 +1,4 @@
-use std::path::PathBuf;
+use std::path::Path;
use image::GenericImageView;
@@ -11,76 +11,76 @@ pub enum TargetDimension {
MaxHeight(u32),
}
-/// Given the path to the original image and the target width/height,
-/// calculate the dimensions of the new image.
+impl TargetDimension {
+ /// Fit the original dimensions into the target constraint
+ /// while maintaining the original aspect ratio.
+ fn fit(&self, orig_dims: (u32, u32)) -> (u32, u32) {
+ let (img_w, img_h) = orig_dims;
+
+ match *self {
+ TargetDimension::MaxWidth(max_w) if max_w >= img_w => orig_dims,
+ TargetDimension::MaxHeight(max_h) if max_h >= img_h => orig_dims,
+
+ TargetDimension::MaxWidth(max_w) => (
+ max_w,
+ ((max_w as f64) * (img_h as f64) / (img_w as f64)).round() as u32,
+ ),
+ TargetDimension::MaxHeight(max_h) => (
+ ((max_h as f64) * (img_w as f64) / (img_h as f64)).round() as u32,
+ max_h,
+ ),
+
+ TargetDimension::BoundingBox(max_w, max_h) => {
+ // Determine constraint by comparing aspect ratio
+ if (max_w as f64) / (max_h as f64) >= (img_w as f64) / (img_h as f64) {
+ TargetDimension::MaxHeight(max_h).fit(orig_dims)
+ } else {
+ TargetDimension::MaxWidth(max_w).fit(orig_dims)
+ }
+ }
+ }
+ }
+}
+
+/// Read the image at the given path and calculate its target thumbnail
+/// dimensions.
///
-/// If the image is smaller than the target dimensions, it will be
-/// left as-is.
+/// Leaves the image at its original size if it's already smaller than
+/// the target constraints.
///
/// TODO: Are there any scenarios in which this division could round
/// one dimension of an image to zero, if it was very tall or very long?
///
-pub fn get_thumbnail_dimensions(
- path: &PathBuf,
+pub fn thumbnail_dimensions(
+ path: impl AsRef<Path>,
target: TargetDimension,
) -> Result<(u32, u32), ThumbnailError> {
let img = image::open(path)?;
- Ok(calculate_dimensions(img.dimensions(), target))
-}
-
-// Calculate the dimensions of the new image, given the original dimensions
-// and target dimensions.
-fn calculate_dimensions(dimensions: (u32, u32), target: TargetDimension) -> (u32, u32) {
- let (img_w, img_h) = dimensions;
-
- match target {
- TargetDimension::MaxWidth(max_w) if max_w >= img_w => dimensions,
- TargetDimension::MaxHeight(max_h) if max_h >= img_h => dimensions,
-
- TargetDimension::MaxWidth(max_w) => (
- max_w,
- ((max_w as f64) * (img_h as f64) / (img_w as f64)).round() as u32,
- ),
- TargetDimension::MaxHeight(max_h) => (
- ((max_h as f64) * (img_w as f64) / (img_h as f64)).round() as u32,
- max_h,
- ),
-
- // The bounding box has a wider aspect ratio than the original image,
- // so filter by height.
- TargetDimension::BoundingBox(max_w, max_h)
- if (max_w as f64) / (max_h as f64) >= (img_w as f64) / (img_h as f64) =>
- {
- calculate_dimensions(dimensions, TargetDimension::MaxHeight(max_h))
- }
- TargetDimension::BoundingBox(max_w, _) => {
- calculate_dimensions(dimensions, TargetDimension::MaxWidth(max_w))
- }
- }
+ Ok(target.fit(img.dimensions()))
}
#[cfg(test)]
-mod test_get_thumbnail_dimensions {
+mod test_thumbnail_dimensions {
use std::path::PathBuf;
use super::*;
- macro_rules! get_thumb_dimensions_tests {
+ macro_rules! target_fit_tests {
($($name:ident: $value:expr,)*) => {
$(
#[test]
fn $name() {
let (input, target, expected) = $value;
- let dimensions = calculate_dimensions(input, target);
+ let dimensions = target.fit(input);
assert_eq!(dimensions, expected);
}
)*
}
}
- get_thumb_dimensions_tests! {
+ target_fit_tests! {
width_lt: ((100, 200), TargetDimension::MaxWidth(50), ( 50, 100)),
width_eq: ((100, 200), TargetDimension::MaxWidth(100), (100, 200)),
width_gt: ((100, 200), TargetDimension::MaxWidth(200), (100, 200)),
@@ -122,7 +122,7 @@ mod test_get_thumbnail_dimensions {
let target = TargetDimension::MaxWidth(50);
- let dimensions = get_thumbnail_dimensions(&p, target);
+ let dimensions = thumbnail_dimensions(&p, target);
assert!(dimensions.is_err());
}
@@ -132,7 +132,7 @@ mod test_get_thumbnail_dimensions {
let target = TargetDimension::MaxWidth(50);
- let dimensions = get_thumbnail_dimensions(&p, target);
+ let dimensions = thumbnail_dimensions(&p, target);
assert!(dimensions.is_err());
}
}
src/main.rs (7867 → 7855)
diff --git a/src/main.rs b/src/main.rs
index 82d26df..6a3cdc2 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -7,12 +7,12 @@ use clap::Parser;
mod create_parent_directory;
mod create_thumbnail;
+mod dimensions;
mod errors;
-mod get_thumbnail_dimensions;
mod is_animated_gif;
use crate::create_thumbnail::create_thumbnail;
-use crate::get_thumbnail_dimensions::TargetDimension;
+use crate::dimensions::TargetDimension;
#[derive(Debug, Parser)]
#[clap(version, about)]
@@ -246,7 +246,7 @@ mod test_cli {
#[cfg(test)]
pub mod test_utils {
- use std::path::PathBuf;
+ use std::path::{Path, PathBuf};
use image::GenericImageView;
@@ -260,7 +260,7 @@ pub mod test_utils {
}
/// Return the dimensions for an image.
- pub fn get_dimensions(path: &PathBuf) -> (u32, u32) {
+ pub fn get_dimensions(path: impl AsRef<Path>) -> (u32, u32) {
let img = image::open(path).unwrap();
img.dimensions()