96 lines
2.7 KiB
Rust
96 lines
2.7 KiB
Rust
use rocket::fs::FileServer;
|
|
use rocket::fs::NamedFile;
|
|
use rocket::http::ContentType;
|
|
use rocket::http::Header;
|
|
|
|
use crate::mushroom;
|
|
use crate::render;
|
|
use crate::translate;
|
|
|
|
pub async fn run_server() {
|
|
rocket::build()
|
|
.mount("/", routes![index, healthz, generate])
|
|
.mount("/static", FileServer::from("static"))
|
|
.launch()
|
|
.await
|
|
.unwrap();
|
|
}
|
|
|
|
#[get("/")]
|
|
async fn index() -> Option<NamedFile> {
|
|
NamedFile::open("static/index.html").await.ok()
|
|
}
|
|
|
|
#[get("/healthz")]
|
|
fn healthz() -> &'static str {
|
|
"ok"
|
|
}
|
|
|
|
// TODO: Wrap this with memoization via https://docs.rs/michie/latest/michie/
|
|
|
|
/// Do work to generate a binary STL for a given mushroom.
|
|
fn generate_binary_stl(mushroom: mushroom::Mushroom) -> Vec<u8> {
|
|
// Generate the binary STL in a byte array.
|
|
let layers = translate::mushroom(&mushroom, 0.1);
|
|
let mesh = render::render(&layers, 0.1);
|
|
|
|
// Generate / return the byte array.
|
|
let mut binary_stl = Vec::<u8>::new();
|
|
stl_io::write_stl(&mut binary_stl, mesh.iter()).unwrap();
|
|
return binary_stl;
|
|
}
|
|
|
|
/// Responder class for BinarySTL or Error.
|
|
#[derive(Responder)]
|
|
enum AsyncBinaryStlResponder {
|
|
#[response(status = 500)]
|
|
Error(&'static str),
|
|
BinaryStl {
|
|
inner: Vec<u8>,
|
|
header: ContentType,
|
|
filename: Header<'static>,
|
|
},
|
|
}
|
|
|
|
/// Take a mushroom struct, and generate a Responder with error handling, and header info.
|
|
async fn generate_helper(mushroom: mushroom::Mushroom) -> AsyncBinaryStlResponder {
|
|
let result = rocket::tokio::task::spawn_blocking(move || {
|
|
// Return the byte array.
|
|
return generate_binary_stl(mushroom);
|
|
})
|
|
.await;
|
|
|
|
return if result.is_ok() {
|
|
AsyncBinaryStlResponder::BinaryStl {
|
|
inner: result.unwrap(),
|
|
header: ContentType::parse_flexible("model/x.stl-binary").unwrap(),
|
|
filename: Header {
|
|
name: "Content-Disposition".into(),
|
|
value: "inline; filename=\"mushroom.stl\"".into(),
|
|
},
|
|
}
|
|
} else {
|
|
AsyncBinaryStlResponder::Error("Internal JoinError")
|
|
};
|
|
}
|
|
|
|
/// Handler for /generate GEt endpoint.
|
|
#[get("/generate?<stalk_h>&<stalk_r>&<cap_h>&<cap_r>&<cap_style>")]
|
|
async fn generate(
|
|
stalk_h: Option<f32>,
|
|
stalk_r: Option<f32>,
|
|
cap_h: Option<f32>,
|
|
cap_r: Option<f32>,
|
|
cap_style: Option<mushroom::CapStyle>,
|
|
) -> AsyncBinaryStlResponder {
|
|
let mushroom = mushroom::Mushroom {
|
|
stalk_h: stalk_h.unwrap_or(66.0),
|
|
stalk_r: stalk_r.unwrap_or(5.0),
|
|
cap_h: cap_h.unwrap_or(34.0),
|
|
cap_r: cap_r.unwrap_or(50.0),
|
|
cap_style: cap_style.unwrap_or(mushroom::CapStyle::Dome),
|
|
};
|
|
|
|
return generate_helper(mushroom).await;
|
|
}
|