🙃
This commit is contained in:
@@ -28,9 +28,9 @@ impl Evaluator {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn set_cell(&mut self, cell_ref: CellRef, raw_val: String) -> Result<(), String> {
|
||||
pub fn set_cell(&mut self, cell_ref: CellRef, raw_val: String) -> Result<Eval, String> {
|
||||
if self.cells.contains_key(&cell_ref) && self.cells[&cell_ref].raw() == raw_val {
|
||||
return Ok(());
|
||||
return self.get_cell(cell_ref);
|
||||
}
|
||||
|
||||
let eval: Eval;
|
||||
@@ -50,19 +50,23 @@ impl Evaluator {
|
||||
}
|
||||
}
|
||||
|
||||
self.cells.insert(cell_ref, Cell::new(eval, raw_val));
|
||||
Ok(())
|
||||
self.cells
|
||||
.insert(cell_ref, Cell::new(eval.clone(), raw_val));
|
||||
Ok(eval)
|
||||
}
|
||||
|
||||
pub fn get_cell(&mut self, cell_ref: CellRef) -> Result<(String, Eval), String> {
|
||||
// pub fn get_cell(&mut self, cell_ref: CellRef) -> Result<(String, Eval), String> {
|
||||
pub fn get_cell(&mut self, cell_ref: CellRef) -> Result<Eval, String> {
|
||||
if !self.cells.contains_key(&cell_ref) {
|
||||
return Err(format!("Cell at {:?} not found.", cell_ref));
|
||||
}
|
||||
|
||||
let cell = &self.cells[&cell_ref];
|
||||
|
||||
Ok((cell.raw(), cell.eval()))
|
||||
// Ok((cell.raw(), cell.eval()))
|
||||
Ok(cell.eval())
|
||||
}
|
||||
|
||||
pub fn add_cell_dep(&mut self, cell_ref: CellRef, dep_ref: CellRef) -> Result<(), String> {
|
||||
if !self.cells.contains_key(&cell_ref) {
|
||||
return Err(format!("Cell at {:?} not found.", cell_ref));
|
||||
@@ -87,7 +91,7 @@ impl Evaluator {
|
||||
fn evaluate_expr(&mut self, expr: &Expr) -> Result<Eval, String> {
|
||||
let res = match expr {
|
||||
Expr::Literal(lit) => Eval::Literal(lit.clone()),
|
||||
Expr::CellRef(re) => self.get_cell(re.to_owned())?.1,
|
||||
Expr::CellRef(re) => self.get_cell(re.to_owned())?,
|
||||
Expr::Infix { op, lhs, rhs } => {
|
||||
let lval = self.evaluate_expr(lhs)?;
|
||||
let rval = self.evaluate_expr(rhs)?;
|
||||
@@ -151,6 +155,14 @@ fn eval_mul(lval: &Eval, rval: &Eval) -> Result<Eval, String> {
|
||||
fn eval_div(lval: &Eval, rval: &Eval) -> Result<Eval, String> {
|
||||
match (lval, rval) {
|
||||
(Eval::Literal(a), Eval::Literal(b)) => {
|
||||
if let (Literal::Integer(_), Literal::Integer(y)) = (a, b) {
|
||||
if *y == 0 {
|
||||
return Err(
|
||||
"Evaluation error: integers attempted to divide by zero.".to_string()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(res) = eval_numeric_infix(a, b, |x, y| x / y, |x, y| x / y) {
|
||||
return Ok(Eval::Literal(res));
|
||||
}
|
||||
|
||||
@@ -80,6 +80,36 @@ async fn main() -> Result<(), Error> {
|
||||
// }
|
||||
}
|
||||
|
||||
// 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 (mut write, mut read) = ws_stream.split();
|
||||
//
|
||||
// // We should not forward messages other than text or binary.
|
||||
// while let Some(msg) = read.try_next().await.unwrap_or(None) {
|
||||
// if msg.is_text() || msg.is_binary() {
|
||||
// if let Err(e) = write
|
||||
// .send(format!("This is a message {}!", msg.to_text().unwrap_or("")).into())
|
||||
// .await
|
||||
// {
|
||||
// eprintln!("send error: {}", e);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// info!("Disconnected from {}", addr);
|
||||
// }
|
||||
|
||||
async fn accept_connection(stream: TcpStream) {
|
||||
let addr = stream
|
||||
.peer_addr()
|
||||
@@ -94,15 +124,57 @@ async fn accept_connection(stream: TcpStream) {
|
||||
|
||||
let (mut write, mut read) = ws_stream.split();
|
||||
|
||||
// We should not forward messages other than text or binary.
|
||||
// Each connection gets its own evaluator
|
||||
let mut evaluator = Evaluator::new();
|
||||
|
||||
while let Some(msg) = read.try_next().await.unwrap_or(None) {
|
||||
if msg.is_text() || msg.is_binary() {
|
||||
if let Err(e) = write
|
||||
.send(format!("This is a message {}!", msg.to_text().unwrap_or("")).into())
|
||||
.await
|
||||
{
|
||||
eprintln!("send error: {}", e);
|
||||
break;
|
||||
if msg.is_text() {
|
||||
let input = msg.to_text().unwrap_or("").trim().to_string();
|
||||
|
||||
let cmds = ["set", "get"];
|
||||
let cmd = &input[0..3.min(input.len())]; // avoid panic on short strings
|
||||
|
||||
if !cmds.iter().any(|c| c == &cmd) {
|
||||
let _ = write
|
||||
.send(format!("ERR invalid command: {}", input).into())
|
||||
.await;
|
||||
continue;
|
||||
}
|
||||
|
||||
let rest = input[4..].trim();
|
||||
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 (value)
|
||||
|
||||
if let Ok(cell_ref) = CellRef::new(raw_ref.to_owned()) {
|
||||
match cmd {
|
||||
"set" => match evaluator.set_cell(cell_ref.clone(), raw_str.to_owned()) {
|
||||
Ok(eval) => {
|
||||
let _ = write.send(format!("{} {}", raw_ref, eval).into()).await;
|
||||
}
|
||||
Err(e) => {
|
||||
let _ = write.send(format!("ERR {}", e).into()).await;
|
||||
}
|
||||
},
|
||||
"get" => match evaluator.get_cell(cell_ref.clone()) {
|
||||
Ok(res) => {
|
||||
let _ = write
|
||||
.send(format!("{} {}", raw_ref, res.to_string()).into())
|
||||
.await;
|
||||
}
|
||||
Err(e) => {
|
||||
let _ = write.send(format!("ERR {}", e).into()).await;
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
let _ = write.send("ERR impossible".into()).await;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let _ = write
|
||||
.send(format!("ERR invalid cell reference: {}", raw_ref).into())
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user