From c5153bdc69c2b03ca850a78f84969b3781a38c2b Mon Sep 17 00:00:00 2001 From: MegaBrutal Date: Mon, 18 Jul 2022 00:30:00 +0200 Subject: [PATCH] Implement apply_to_canvas to avoid redundant code It takes a closure and applies it to the canvas. --- src/main.rs | 75 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 19 deletions(-) diff --git a/src/main.rs b/src/main.rs index 302fb3a..4618550 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +use std::convert::From; use std::io::Cursor; use std::fmt::Display; use std::fmt; @@ -43,7 +44,8 @@ impl ResponseError for ImageError { #[derive(Debug)] enum CanvasError { NotExists, - DimensionMismatch + DimensionMismatch, + ImageError(ImageError) } impl Display for CanvasError { @@ -56,18 +58,26 @@ impl ResponseError for CanvasError { fn status_code(&self) -> StatusCode { match &self { CanvasError::NotExists => StatusCode::NOT_FOUND, - CanvasError::DimensionMismatch => StatusCode::BAD_REQUEST + CanvasError::DimensionMismatch => StatusCode::BAD_REQUEST, + CanvasError::ImageError(e) => e.status_code() } } fn error_response(&self) -> HttpResponse { match &self { CanvasError::NotExists => HttpResponse::NotFound().body("Canvas does not exist."), - CanvasError::DimensionMismatch => HttpResponse::BadRequest().body("Supplied dimensions don't much the dimensions of existing canvas.") + CanvasError::DimensionMismatch => HttpResponse::BadRequest().body("Supplied dimensions don't much the dimensions of existing canvas."), + CanvasError::ImageError(e) => e.error_response() } } } +impl From for CanvasError { + fn from(e: ImageError) -> CanvasError { + CanvasError::ImageError(e) + } +} + struct ToRgbIter<'a, T> where T: AsPrimitive { iter: Box<&'a mut dyn Iterator> } @@ -99,6 +109,15 @@ fn to_imageresult (result: Result) -> Result (result: Result) -> Result { + println!("Converting to canvasresult: {:?}", result); + match result { + Ok(v) => Ok(v), + Err(e) => Err(CanvasError::ImageError(e)) + } +} + +#[derive(Debug)] struct Canvas { pen: usize, img: RgbImage @@ -157,6 +176,34 @@ fn rgb_encode(img: RgbImage, data: &mut dyn Iterator) -> Result(f: F, canvas_option: &'a mut Option, dimensions: Option<(u32, u32)>, data: &str) -> Result<&'a mut Canvas, CanvasError> + where F: Fn(Canvas, &mut dyn Iterator) -> Result +{ + let canvas = match canvas_option.take() { + Some(canvas) => match dimensions { + Some(dimensions) => { + if dimensions == canvas.img.dimensions() { + Ok(canvas) + } + else { + _ = canvas_option.insert(canvas); + Err(CanvasError::DimensionMismatch) + } + }, + None => + Ok(canvas) + }, + None => match dimensions { + Some((dim_x, dim_y)) => + Ok(Canvas::new(dim_x, dim_y)), + None => + Err(CanvasError::NotExists) + } + }?; + + Ok(canvas_option.insert(f(canvas, percent_decode_str(&data).into_iter().borrow_mut())?)) +} + fn make_png(dim_x: u32, dim_y: u32, scale: u32, data: &mut dyn Iterator) -> Result>, ImageError> { // Image must not be larger than 1 megapixel if dim_x * dim_y * scale > 1048576 { @@ -197,12 +244,10 @@ async fn img_pgen0(req: HttpRequest, canvas0: web::Data let data = req.uri().path().split("/").skip(3).next().unwrap(); let mut cursor = Cursor::new(Vec::new()); let scale = 16; - let img: RgbImage = { + let img: RgbImage = ({ let canvas_option = &mut *canvas0.lock().unwrap(); - let canvas = canvas_option.take().ok_or(CanvasError::NotExists)?; - let canvas = rgb_encode_to_canvas(canvas, percent_decode_str(&data).into_iter().borrow_mut())?; - canvas_option.insert(canvas).img.clone() - }; + Ok(apply_to_canvas( |c, d| to_canvasresult(rgb_encode_to_canvas(c, d)), canvas_option, None, data)?.img.clone()) + } as Result)?; let (tdim_x, tdim_y) = img.dimensions(); let (tdim_x, tdim_y) = (tdim_x * scale, tdim_y * scale); let img = resize(&img, tdim_x, tdim_y, FilterType::Nearest); @@ -216,18 +261,10 @@ async fn img_pgen0(req: HttpRequest, canvas0: web::Data async fn img_pgen1(req: HttpRequest, path: web::Path<(u32, u32, u32)>, canvas1: web::Data>>>) -> Result { let (dim_x, dim_y, scale) = path.into_inner(); let data = req.uri().path().split("/").skip(6).next().unwrap(); - let img: RgbImage = { + let img: RgbImage = ({ let canvas_option = &mut *canvas1.lock().unwrap(); - let canvas = canvas_option.take().unwrap_or_else( || Canvas::new(dim_x, dim_y) ); - if (dim_x, dim_y) == canvas.img.dimensions() { - let canvas = rgb_encode_to_canvas(canvas, percent_decode_str(&data).into_iter().borrow_mut())?; - Ok(canvas_option.insert(canvas).img.clone()) - } - else { - _ = canvas_option.insert(canvas); - Err(CanvasError::DimensionMismatch) - } - }?; + Ok(apply_to_canvas( |c, d| to_canvasresult(rgb_encode_to_canvas(c, d)), canvas_option, Some((dim_x, dim_y)), data)?.img.clone()) + } as Result)?; let (tdim_x, tdim_y) = img.dimensions(); let (tdim_x, tdim_y) = (tdim_x * scale, tdim_y * scale); let img = resize(&img, tdim_x, tdim_y, FilterType::Nearest); -- 2.34.1