This commit is contained in:
Adam Chalmers
2024-06-06 16:09:27 -05:00
parent 9df69fb1c2
commit c6f43cb607
6 changed files with 138 additions and 8 deletions

View File

@ -1138,6 +1138,16 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "http-body"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643"
dependencies = [
"bytes",
"http 1.1.0",
]
[[package]]
name = "httparse"
version = "1.8.0"
@ -1162,7 +1172,7 @@ dependencies = [
"futures-util",
"h2",
"http 0.2.12",
"http-body",
"http-body 0.4.6",
"httparse",
"httpdate",
"itoa",
@ -1174,6 +1184,21 @@ dependencies = [
"want",
]
[[package]]
name = "hyper"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d"
dependencies = [
"bytes",
"http 1.1.0",
"http-body 1.0.0",
"httpdate",
"pin-project-lite",
"smallvec",
"tokio",
]
[[package]]
name = "hyper-rustls"
version = "0.24.2"
@ -1182,7 +1207,7 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
dependencies = [
"futures-util",
"http 0.2.12",
"hyper",
"hyper 0.14.29",
"rustls 0.21.12",
"tokio",
"tokio-rustls 0.24.1",
@ -1434,6 +1459,15 @@ dependencies = [
"syn 2.0.66",
]
[[package]]
name = "kcl-test-server"
version = "0.1.0"
dependencies = [
"hyper 1.3.1",
"kcl-lib",
"tokio",
]
[[package]]
name = "kittycad"
version = "0.3.3"
@ -2095,8 +2129,8 @@ dependencies = [
"futures-util",
"h2",
"http 0.2.12",
"http-body",
"hyper",
"http-body 0.4.6",
"hyper 0.14.29",
"hyper-rustls",
"ipnet",
"js-sys",
@ -2165,7 +2199,7 @@ dependencies = [
"futures",
"getrandom",
"http 0.2.12",
"hyper",
"hyper 0.14.29",
"parking_lot 0.11.2",
"reqwest",
"reqwest-middleware",
@ -3444,7 +3478,7 @@ dependencies = [
"console_error_panic_hook",
"futures",
"gloo-utils",
"hyper",
"hyper 0.14.29",
"image",
"js-sys",
"kcl-lib",

View File

@ -65,6 +65,7 @@ members = [
"derive-docs",
"kcl",
"kcl-macros",
"kcl-test-server",
]
[workspace.dependencies]

View File

@ -0,0 +1,9 @@
[package]
name = "kcl-test-server"
version = "0.1.0"
edition = "2021"
[dependencies]
hyper = { version = "1.3.1", features = ["server"] }
kcl-lib = { path = "../kcl" }
tokio = { version = "1.38.0", features = ["macros", "rt-multi-thread"] }

View File

@ -0,0 +1,67 @@
use std::net::SocketAddr;
use hyper::header::CONTENT_TYPE;
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Error, Response, Server};
use kcl_lib::executor::ExecutorContext;
use kcl_lib::settings::types::UnitLength;
use crate::new_context;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let listen_on = std::env::args().skip(1).next().unwrap();
start(listen_on).await?
}
pub async fn start(listen_on: SocketAddr) -> anyhow::Result<()> {
let state: ExecutorContext = new_context(UnitLength::Mm).await?;
// In hyper, a `MakeService` is basically your server.
// It makes a `Service` for each connection, which manages the connection.
let make_service = make_service_fn(
// This closure is run for each connection.
move |_| {
let state = state.clone();
async move {
// This is the `Service` which handles the connection.
// `service_fn` converts a function which returns a Response
// into a `Service`.
Ok::<_, Error>(service_fn(move |req| {
// Return a response.
async move {
let whole_body = hyper::body::to_bytes(req.into_body()).await?;
let Ok(kcl_src_code) = String::from_utf8(whole_body.into()) else {
return Ok(bad_request("Body was not UTF-8".to_owned()));
};
let parser = match kcl_lib::token::lexer(&kcl_src_code) {
Ok(t) => kcl_lib::parser::Parser::new(t),
Err(e) => return Ok(bad_request(format!("tokenization error: {e}"))),
};
let program = match parser.ast() {
Ok(p) => p,
Err(e) => return Ok(bad_request(format!("Parse error: {e}"))),
};
let png_bytes: Vec<u8> = todo!();
let mut resp = Response::new(Body::from(png_bytes));
resp.headers_mut().insert(CONTENT_TYPE, "image/png".parse().unwrap());
Ok::<_, Error>(resp)
}
}))
}
},
);
let server = Server::bind(&listen_on).serve(make_service);
println!("Listening on {listen_on}");
if let Err(e) = server.await {
eprintln!("Server error: {e}");
return Err(e.into());
}
Ok(())
}
fn bad_request(msg: String) -> Response<Body> {
let mut resp = Response::new(Body::from(msg));
*resp.status_mut() = hyper::StatusCode::BAD_REQUEST;
resp
}

View File

@ -4,8 +4,6 @@ use kcl_lib::{
settings::types::UnitLength,
};
// mod server;
async fn new_context(units: UnitLength) -> Result<ExecutorContext> {
let user_agent = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),);
let http_client = reqwest::Client::builder()
@ -1959,3 +1957,23 @@ async fn serial_test_neg_xz_plane() {
let result = execute_and_snapshot(code, UnitLength::Mm).await.unwrap();
twenty_twenty::assert_image("tests/executor/outputs/neg_xz_plane.png", &result, 1.0);
}
#[tokio::test(flavor = "multi_thread")]
async fn start_server() {
let server_url = "0.0.0.0:3333";
tokio::task::spawn(server::start(server_url.parse().unwrap()));
let code = r#"const part001 = startSketchOn('-XZ')
|> startProfileAt([0, 0], %)
|> lineTo([100, 100], %)
|> lineTo([100, 0], %)
|> close(%)
|> extrude(5 + 7, %)
"#;
let client = reqwest::Client::new();
client
.post(format!("http://{server_url}"))
.body(code)
.send()
.await
.unwrap();
}

View File

@ -0,0 +1 @@