Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
pohlm01 committed Oct 13, 2023
1 parent e42caa7 commit 091f328
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 76 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ serde = {version = "1.0", features = ["derive"] }
tokio = { version = "1.32", features = ["full"] }
bytes = "1.5"
futures = "0.3.28"
mime = "0.3"
mime = "0.3"
async-trait = "0.1.73"
20 changes: 20 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use image::ImageError;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum Error {
#[error("Storage error: {0}")]
Storage(#[from] object_store::Error),
#[error("Invalid path: {0}")]
Path(#[from] object_store::path::Error),
#[error("Configuration error: {0}")]
Config(#[from] config::ConfigError),
#[error("Image error: {0}")]
Image(#[from] ImageError),
#[error("Image format not supported")]
NotSupported,
#[error("Utf-8 error")]
Utf,
}

pub type ThumbsResult<T> = Result<T, Error>;
28 changes: 7 additions & 21 deletions src/gcs.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::{ImageThumbs, ThumbsResult};
use config::Config;
use object_store::gcp::{GoogleCloudStorage, GoogleCloudStorageBuilder};
use object_store::ClientOptions;

use crate::{ImageThumbs, ThumbsResult};

impl ImageThumbs<GoogleCloudStorage> {
/// Create new ImageThumbs instance connected to Google Cloud Storage using the environment
Expand All @@ -14,26 +13,13 @@ impl ImageThumbs<GoogleCloudStorage> {
/// # Arguments
/// * config - Path to the config file from the crate root (`.yaml` may be omitted)
pub async fn new(config: &str) -> ThumbsResult<Self> {
let settings = Config::builder()
.add_source(config::File::with_name(config))
.build()?
.get("thumbs")?;

#[allow(unused_mut)]
let mut client_options = ClientOptions::new()
.with_content_type_for_suffix("jpg", mime::IMAGE_JPEG.to_string())
.with_content_type_for_suffix("jpeg", mime::IMAGE_JPEG.to_string())
.with_content_type_for_suffix("png", mime::IMAGE_PNG.to_string());

#[cfg(test)]
{
client_options = client_options.with_allow_http(true);
}

let client = GoogleCloudStorageBuilder::from_env()
.with_client_options(client_options)
.with_client_options(Self::client_options())
.build()?;

Ok(Self { client, settings })
Ok(Self {
client,
settings: Self::settings(config)?,
})
}
}
3 changes: 2 additions & 1 deletion src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use image::{load_from_memory_with_format, ImageFormat};
use object_store::path::Path;
use object_store::ObjectStore;

use crate::{Error, ImageDetails, ImageThumbs, Mode, ThumbsResult};
use crate::model::{ImageDetails, Mode};
use crate::{Error, ImageThumbs, ThumbsResult};

impl<T: ObjectStore> ImageThumbs<T> {
pub(crate) async fn create_thumbs_from_bytes(
Expand Down
69 changes: 18 additions & 51 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,60 +1,20 @@
use ::image::{ImageError, ImageFormat};
use ::image::ImageFormat;
use config::Config;
use object_store::path::Path;
use object_store::ObjectStore;
use serde::Deserialize;
use thiserror::Error;

pub use crate::error::Error;
pub use crate::error::ThumbsResult;
pub use crate::model::ImageThumbs;
use crate::model::Params;

mod error;
mod gcs;
mod image;
mod model;
mod storage;

#[derive(Error, Debug)]
pub enum Error {
#[error("Storage error: {0}")]
Storage(#[from] object_store::Error),
#[error("Invalid path: {0}")]
Path(#[from] object_store::path::Error),
#[error("Configuration error: {0}")]
Config(#[from] config::ConfigError),
#[error("Image error: {0}")]
Image(#[from] ImageError),
#[error("Image format not supported")]
NotSupported,
#[error("Utf-8 error")]
Utf,
}

pub type ThumbsResult<T> = Result<T, Error>;

#[derive(Debug)]
pub struct ImageThumbs<T: ObjectStore> {
client: T,
settings: Vec<Params>,
}

#[derive(Deserialize, Debug, Clone)]
struct Params {
name: String,
quality: u8,
size: (u32, u32),
mode: Mode,
}

#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "snake_case")]
enum Mode {
Fit,
Crop,
}

#[derive(Debug)]
struct ImageDetails {
stem: String,
format: ImageFormat,
path: Path,
bytes: Vec<u8>,
}

impl<T: ObjectStore> ImageThumbs<T> {
/// Get image from object storage, create thumbnails, and put them in the `dest_dir` directory
pub async fn create_thumbs_dir(
Expand Down Expand Up @@ -111,18 +71,25 @@ impl<T: ObjectStore> ImageThumbs<T> {
.await?;
self.upload_thumbs(thumbs).await
}

fn settings(config: &str) -> ThumbsResult<Vec<Params>> {
Ok(Config::builder()
.add_source(config::File::with_name(config))
.build()?
.get("thumbs")?)
}
}

#[cfg(test)]
mod tests {
use crate::model::ImageDetails;
use crate::ImageThumbs;
use image::ImageFormat;
use object_store::path::Path;
use object_store::ObjectStore;
use tokio::fs::File;
use tokio::io::{AsyncReadExt, BufReader};

use crate::{ImageDetails, ImageThumbs};

#[tokio::test]
async fn from_cloud() {
let client = ImageThumbs::new("src/test/image_thumbs").await.unwrap();
Expand Down
32 changes: 32 additions & 0 deletions src/model.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use image::ImageFormat;
use object_store::path::Path;
use serde::Deserialize;

#[derive(Debug)]
pub struct ImageThumbs<T> {
pub(crate) client: T,
pub(crate) settings: Vec<Params>,
}

#[derive(Deserialize, Debug, Clone)]
pub(crate) struct Params {
pub(crate) name: String,
pub(crate) quality: u8,
pub(crate) size: (u32, u32),
pub(crate) mode: Mode,
}

#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "snake_case")]
pub(crate) enum Mode {
Fit,
Crop,
}

#[derive(Debug)]
pub(crate) struct ImageDetails {
pub(crate) stem: String,
pub(crate) format: ImageFormat,
pub(crate) path: Path,
pub(crate) bytes: Vec<u8>,
}
19 changes: 17 additions & 2 deletions src/storage.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,26 @@
use image::ImageFormat;
use object_store::path::{Path, PathPart};
use object_store::{ObjectMeta, ObjectStore};
use object_store::{ClientOptions, ObjectMeta, ObjectStore};

use crate::model::ImageDetails;
use crate::Error::NotSupported;
use crate::{ImageDetails, ImageThumbs, ThumbsResult};
use crate::{ImageThumbs, ThumbsResult};

impl<T: ObjectStore> ImageThumbs<T> {
pub(crate) fn client_options() -> ClientOptions {
#[allow(unused_mut)]
let mut client_options = ClientOptions::new()
.with_content_type_for_suffix("jpg", mime::IMAGE_JPEG.to_string())
.with_content_type_for_suffix("jpeg", mime::IMAGE_JPEG.to_string())
.with_content_type_for_suffix("png", mime::IMAGE_PNG.to_string());

#[cfg(test)]
{
client_options = client_options.with_allow_http(true);
}
client_options
}

pub(crate) async fn upload_thumbs(&self, images: Vec<ImageDetails>) -> ThumbsResult<()> {
for image in images {
let path = Self::generate_path(&image.path, &image.stem, &image.format);
Expand Down

0 comments on commit 091f328

Please sign in to comment.