Skip to main content

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()