bab5da743def470f5421a99bed554db0611a8b26
[litoprism.git] / src / main.rs
1 use std::io::Cursor;
2 use std::fmt::Display;
3 use std::fmt;
4 use actix_web::{get, web, App, HttpServer, HttpResponse, Responder, ResponseError, Result};
5 use actix_web::body::BoxBody;
6 use actix_web::http::StatusCode;
7 use image::{ImageBuffer, ColorType, RgbImage, write_buffer_with_format};
8 use image::ImageOutputFormat::Png;
9
10 #[derive(Debug)]
11 struct ImageError(image::ImageError);
12
13 impl Display for ImageError {
14 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15 write!(f, "{}", &self.0)
16 }
17 }
18
19 impl ResponseError for ImageError {
20 fn status_code(&self) -> StatusCode {
21 StatusCode::INTERNAL_SERVER_ERROR
22 }
23
24 fn error_response(&self) -> HttpResponse<BoxBody> {
25 HttpResponse::InternalServerError().finish()
26 }
27 }
28
29 fn to_imageresult<T> (result: Result<T, image::ImageError>) -> Result<T, ImageError> {
30 match result {
31 Ok(v) => Ok(v),
32 Err(e) => Err(ImageError(e))
33 }
34 }
35
36 #[get("/hello/{name}")]
37 async fn greet(name: web::Path<String>) -> impl Responder {
38 format!("Hello {name}!")
39 }
40
41 #[get("/gen/{data}")]
42 async fn img_gen(data: web::Path<String>) -> Result<impl Responder> {
43 let mut cursor = Cursor::new(Vec::new());
44 let mut img: RgbImage = ImageBuffer::new(128, 128);
45 let mut pixels = img.pixels_mut();
46
47 for c in data.chars() {
48 let mut p = pixels.next().unwrap();
49 p.0 = [c as u8, 0, 0];
50 }
51
52 to_imageresult(write_buffer_with_format(&mut cursor, &img, 128, 128, ColorType::Rgb8, Png))?;
53 Ok(HttpResponse::build(StatusCode::OK)
54 .content_type("image/png")
55 .body(cursor.into_inner()))
56 }
57
58 #[actix_web::main] // or #[tokio::main]
59 async fn main() -> std::io::Result<()> {
60 HttpServer::new(|| {
61 App::new().service(greet).service(img_gen)
62 })
63 .bind(("127.0.0.1", 8080))?
64 .run()
65 .await
66 }