-use actix_web::{get, web, App, HttpServer, Responder};
+use std::io::Cursor;
+use std::fmt::Display;
+use std::fmt;
+use actix_web::{get, web, App, HttpServer, HttpResponse, Responder, ResponseError, Result};
+use actix_web::body::BoxBody;
+use actix_web::http::StatusCode;
+use image::{ImageBuffer, ColorType, RgbImage, write_buffer_with_format};
+use image::ImageOutputFormat::Png;
+
+#[derive(Debug)]
+struct ImageError(image::ImageError);
+
+impl Display for ImageError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}", &self.0)
+ }
+}
+
+impl ResponseError for ImageError {
+ fn status_code(&self) -> StatusCode {
+ StatusCode::INTERNAL_SERVER_ERROR
+ }
+
+ fn error_response(&self) -> HttpResponse<BoxBody> {
+ HttpResponse::InternalServerError().finish()
+ }
+}
+
+fn to_imageresult<T> (result: Result<T, image::ImageError>) -> Result<T, ImageError> {
+ match result {
+ Ok(v) => Ok(v),
+ Err(e) => Err(ImageError(e))
+ }
+}
#[get("/hello/{name}")]
async fn greet(name: web::Path<String>) -> impl Responder {
format!("Hello {name}!")
}
+#[get("/gen/{data}")]
+async fn img_gen(data: web::Path<String>) -> Result<impl Responder> {
+ let mut cursor = Cursor::new(Vec::new());
+ let img: RgbImage = ImageBuffer::new(512, 512);
+ to_imageresult(write_buffer_with_format(&mut cursor, &img, 512, 512, ColorType::Rgb8, Png))?;
+ Ok(cursor.into_inner().customize().insert_header(("content-type", "image/png")))
+}
+
#[actix_web::main] // or #[tokio::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
- App::new().service(greet)
+ App::new().service(greet).service(img_gen)
})
.bind(("127.0.0.1", 8080))?
.run()