This commit is contained in:
2025-09-02 02:19:56 +10:00
parent 5a45ed1f2b
commit e4c39ba83b
4 changed files with 325 additions and 969 deletions

1157
backend/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,4 +4,7 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
websocket = "0.27.1" futures-util = "0.3.31"
log = "0.4.27"
tokio = { version = "1.47.1", features = ["rt-multi-thread", "macros", "net", "time"] }
tokio-tungstenite = "0.27.0"

View File

@@ -3,13 +3,15 @@ mod evaluator;
mod parser; mod parser;
mod tokenizer; mod tokenizer;
use std::io; use futures_util::{StreamExt, TryStreamExt, future};
use log::info;
use websocket::server::WsServer; use std::{env, io::Error};
use tokio::net::{TcpListener, TcpStream};
use crate::{cell::CellRef, evaluator::Evaluator}; use crate::{cell::CellRef, evaluator::Evaluator};
fn main() { #[tokio::main]
async fn main() -> Result<(), Error> {
// let mut input = String::new(); // let mut input = String::new();
// io::stdin().read_line(&mut input).expect("Expected input."); // io::stdin().read_line(&mut input).expect("Expected input.");
@@ -21,49 +23,79 @@ fn main() {
// evaluator.set_cell(a1, input).unwrap(); // evaluator.set_cell(a1, input).unwrap();
// println!("{:?}", evaluator.get_cell(a1).unwrap()); // println!("{:?}", evaluator.get_cell(a1).unwrap());
println!("CMDS : set <cell_ref>, get <cell_ref>"); let addr = env::args()
loop { .nth(1)
let mut input = String::new(); .unwrap_or_else(|| "127.0.0.1:7050".to_string());
io::stdin().read_line(&mut input).expect("Expected input.");
let cmds = ["set", "get"]; // Create the event loop and TCP listener we'll accept connections on.
let cmd = &input[0..3]; let try_socket = TcpListener::bind(&addr).await;
if !cmds.iter().any(|c| c == &cmd) { let listener = try_socket.expect("Failed to bind");
println!("{} is an invalid command!", cmd); info!("Listening on: {}", addr);
println!("CMDS : set <cell_ref>, get <cell_ref>");
continue;
}
let rest = &input[4..]; while let Ok((stream, _)) = listener.accept().await {
let mut parts = rest.splitn(2, char::is_whitespace); tokio::spawn(accept_connection(stream));
let raw_ref = parts.next().unwrap_or("").trim(); // cell reference
let raw_str = parts.next().unwrap_or("").trim(); // rest of the string (value)
// println!("{} {}", raw_ref, raw_str);
if let Ok(cell_ref) = CellRef::new(raw_ref.to_owned()) {
match cmd {
"set" => match evaluator.set_cell(cell_ref, raw_str.to_owned()) {
Ok(_) => println!("Successfully set cell {} to {}.", raw_ref, raw_str),
Err(e) => println!("{}", e),
},
"get" => match evaluator.get_cell(cell_ref) {
Ok(res) => println!("{:?}", res),
Err(e) => println!("{}", e),
},
_ => {
panic!("Impossible.");
}
}
} else {
println!("{} is an invalid cell reference!", raw_ref);
continue;
}
} }
// let rt = Runtime::new().unwrap(); Ok(())
let handle = rt.handle().clone();
// let addr = "127.0.0.1:7050"; // println!("CMDS : set <cell_ref>, get <cell_ref>");
// loop {
// let mut input = String::new();
// io::stdin().read_line(&mut input).expect("Expected input.");
// //
// let socket = WsServer::bind(addr, handle); // let cmds = ["set", "get"];
// let cmd = &input[0..3];
// if !cmds.iter().any(|c| c == &cmd) {
// println!("{} is an invalid command!", cmd);
// println!("CMDS : set <cell_ref>, get <cell_ref>");
// continue;
// }
//
// let rest = &input[4..];
// let mut parts = rest.splitn(2, char::is_whitespace);
//
// let raw_ref = parts.next().unwrap_or("").trim(); // cell reference
// let raw_str = parts.next().unwrap_or("").trim(); // rest of the string (value)
// // println!("{} {}", raw_ref, raw_str);
//
// if let Ok(cell_ref) = CellRef::new(raw_ref.to_owned()) {
// match cmd {
// "set" => match evaluator.set_cell(cell_ref, raw_str.to_owned()) {
// Ok(_) => println!("Successfully set cell {} to {}.", raw_ref, raw_str),
// Err(e) => println!("{}", e),
// },
// "get" => match evaluator.get_cell(cell_ref) {
// Ok(res) => println!("{:?}", res),
// Err(e) => println!("{}", e),
// },
// _ => {
// panic!("Impossible.");
// }
// }
// } else {
// println!("{} is an invalid cell reference!", raw_ref);
// continue;
// }
// }
}
async fn accept_connection(stream: TcpStream) {
let addr = stream
.peer_addr()
.expect("connected streams should have a peer address");
info!("Peer address: {}", addr);
let ws_stream = tokio_tungstenite::accept_async(stream)
.await
.expect("Error during the websocket handshake occurred");
info!("New WebSocket connection: {}", addr);
let (write, read) = ws_stream.split();
// We should not forward messages other than text or binary.
read.try_filter(|msg| future::ready(msg.is_text() || msg.is_binary()))
.forward(write)
.await
.expect("Failed to forward messages");
} }

View File

@@ -1,15 +1,13 @@
<script lang="ts"> <script lang="ts">
let socket = new WebSocket("ws://localhost:7050"); const ws = new WebSocket("ws://127.0.0.1:7050");
ws.onmessage = (e) => console.log("->", e.data);
socket.onopen((event: Event) => { let input: string = "";
});
socket.onmessage((event: MessageEvent) => {});
</script> </script>
<main> <main>
<h1>Lead</h1> <h1>Lead</h1>
<button onclick={() => ws.send(input)}>Send msg</button>
<input bind:value={input} />
</main> </main>
<style> <style>