From 7afcfa727b5ca1fef26eb25d8b6e017b049e8b42 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sun, 5 Mar 2023 11:56:46 +0100 Subject: [PATCH] implement more --- assets/index.html | 101 +++++++++++++++++++++++++++++++++++----------- src/bootstrap.rs | 24 +++++++++++ src/main.rs | 47 +++++++++++++++++---- 3 files changed, 142 insertions(+), 30 deletions(-) diff --git a/assets/index.html b/assets/index.html index 285196f..445c173 100644 --- a/assets/index.html +++ b/assets/index.html @@ -28,6 +28,21 @@ display: flex; margin-bottom: 10px; } + + #compilers-wrapper { + display: flex; + height: 100px; + } + + .compiler { + height: 70px; + width: 150px; + display: flex; + align-items: center; + justify-content: center; + border: 1px black solid; + background: rgb(185, 210, 181); + } @@ -36,7 +51,14 @@
LIBRARY
- +
+ + +

@@ -45,33 +67,66 @@ diff --git a/src/bootstrap.rs b/src/bootstrap.rs index aadcb56..294199b 100644 --- a/src/bootstrap.rs +++ b/src/bootstrap.rs @@ -3,6 +3,7 @@ use std::{path::Path, pin::Pin, process::Stdio}; use axum::extract::ws::{self, WebSocket}; use color_eyre::{eyre::Context, Result}; use futures::{stream::SplitSink, SinkExt}; +use serde::Serialize; use tokio::{ io::{AsyncRead, AsyncReadExt}, process::{Child, Command}, @@ -36,6 +37,29 @@ pub async fn build_a_compiler( Ok(()) } +#[derive(Debug, Clone, Serialize)] +pub enum Compiler { + Bootstrap, + Dev, + Dist, +} + +pub async fn list_compilers(entrypoint: &Path) -> Vec { + let mut compilers = vec![Compiler::Bootstrap]; + + let build = entrypoint.parent().unwrap().join("build/host"); + + if let Ok(true) = tokio::fs::try_exists(build.join("stage1").join("bin").join("rustc")).await { + compilers.push(Compiler::Dev); + } + + if let Ok(true) = tokio::fs::try_exists(build.join("stage2").join("bin").join("rustc")).await { + compilers.push(Compiler::Dist); + } + + compilers +} + async fn handle_stdouts( mut stdout: Pin>, mut stderr: Pin>, diff --git a/src/main.rs b/src/main.rs index ebe1bfa..1d3172e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,15 +5,16 @@ use std::{net::SocketAddr, path::PathBuf}; use axum::{ extract::{ - ws::{Message, WebSocket}, + ws::{CloseFrame, Message, WebSocket}, ConnectInfo, TypedHeader, WebSocketUpgrade, }, response::IntoResponse, routing::get, Router, }; -use futures::stream::StreamExt; -use serde::Serialize; +use bootstrap::Compiler; +use futures::{stream::StreamExt, SinkExt}; +use serde::{Deserialize, Serialize}; use tower_http::{ services::ServeDir, trace::{DefaultMakeSpan, TraceLayer}, @@ -94,6 +95,13 @@ async fn ws_handler( enum ServerMessage<'a> { Stdout(&'a str), Stderr(&'a str), + AvailableCompilers(Vec), +} + +#[derive(Debug, Clone, Deserialize)] +enum ClientMessage { + Compile, + ListCompilers, } impl<'a> From> for Message { @@ -136,10 +144,35 @@ async fn handle_socket(mut socket: WebSocket, who: SocketAddr, entrypoint: PathB while let Some(Ok(msg)) = receiver.next().await { info!(?msg); - if let Message::Text(msg) = msg { - if msg == "bootstrap me" { - if let Err(err) = bootstrap::build_a_compiler(&mut sender, &entrypoint).await { - error!(%err); + if let Message::Text(msg_str) = msg { + let msg = serde_json::from_str::(&msg_str); + + match msg { + Ok(ClientMessage::Compile) => { + if let Err(err) = bootstrap::build_a_compiler(&mut sender, &entrypoint).await { + error!(%err); + } + } + Ok(ClientMessage::ListCompilers) => { + let compilers = bootstrap::list_compilers(&entrypoint).await; + if let Err(err) = sender + .send(ServerMessage::AvailableCompilers(compilers).into()) + .await + { + error!(%err); + } + } + Err(err) => { + error!(?err, ?msg_str, "invalid client message"); + if let Err(err) = sender + .send(Message::Close(Some(CloseFrame { + code: 0, + reason: "invalid message, you naughty".into(), + }))) + .await + { + error!(%err); + } } } }