image.rs
1.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use std::fmt::Display;
use crate::{models::image, AppData, error::Error};
use actix_web::{Error as ActixError, web, http::StatusCode};
use anyhow::Result;
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
#[serde (rename_all = "lowercase")]
pub enum Size {
Original,
Large,
Medium,
Small,
Thumbnail
}
#[derive(Debug, Deserialize, Serialize)]
pub struct SizeQuery {
size :Option<Size>,
}
impl Display for Size {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let size_str = match self {
Size::Original => "original",
Size::Large => "large",
Size::Medium => "medium",
Size::Small => "small",
Size::Thumbnail => "thumbnail"
};
write!(f, "{}", size_str)
}
}
pub async fn get_image( app_data: web::Data<AppData>
, ident: web::Path<i32>
, size: web::Query<SizeQuery>
) -> Result<actix_files::NamedFile, ActixError>
{
let pool = app_data.database_pool.clone();
let ident = ident.into_inner();
let size = size.into_inner().size.unwrap_or(Size::Large);
let image = web::block(move || image::get_image(pool, ident)).await?;
let path = image.clone().context()
. path(size).await
. ok_or(Error::new( "Image not ready"
, StatusCode::SERVICE_UNAVAILABLE ))?;
Ok( actix_files::NamedFile::open(path)?
. set_content_type( image.mime_type
. parse()
. map_err(|e| Error::from(e))? )
. disable_content_disposition() )
}