usestd::{ops::{Add,Div,Mul,Sub},str::FromStr,};macro_rules!apply_op{($op:ident,$tokens:ident,$idx:ident)=>{{$tokens[$idx-1]=Token::Num($tokens[$idx-1].as_num()?.$op($tokens[$idx+1].as_num()?));$tokens.remove($idx+1);$tokens.remove($idx);}};}#[derive(Debug)]enumCalcError{Op,Input,}#[derive(Debug,Clone,Copy,PartialEq)]enumOp{Add,Sub,Mul,Div,}implFromStrforOp{typeErr=CalcError;fnfrom_str(s:&str)->Result<Self,Self::Err>{matchs{"+"=>Ok(Op::Add),"-"=>Ok(Op::Sub),"*"=>Ok(Op::Mul),"/"=>Ok(Op::Div),_=>Err(CalcError::Input),}}}#[derive(Debug,Clone,Copy,PartialEq)]enumToken{Num(i64),Op(Op),}implToken{fnas_num(&mutself)->Result<i64,CalcError>{matchself{Token::Num(x)=>Ok(*x),_=>Err(CalcError::Op),}}}implFromStrforToken{typeErr=CalcError;fnfrom_str(s:&str)->Result<Self,Self::Err>{ifletOk(x)=s.parse::<i64>(){returnOk(Token::Num(x));}else{letop=Op::from_str(s)?;returnOk(Token::Op(op));}}}fneval_str(s:&str)->Result<i64,CalcError>{letmuttokens=tokenize(s)?;letmuti=0;// do mul/divloop{// check if there are anyletops:Vec<&Token>=tokens.iter().filter(|e|**e==Token::Op(Op::Div)||**e==Token::Op(Op::Mul)).collect();ifops.is_empty(){break;}ifletSome(token)=tokens.get(i){ifletToken::Op(op)=*token{matchop{Op::Div=>apply_op!(div,tokens,i),Op::Mul=>apply_op!(mul,tokens,i),_=>{}}}i+=1;}else{// start again from the topi=0;}}i=0;// do add/subloop{// check if there are anyletops:Vec<&Token>=tokens.iter().filter(|e|**e==Token::Op(Op::Add)||**e==Token::Op(Op::Sub)).collect();ifops.is_empty(){break;}ifletSome(token)=tokens.get(i){ifletToken::Op(op)=*token{matchop{Op::Add=>apply_op!(add,tokens,i),Op::Sub=>apply_op!(sub,tokens,i),_=>{}}}i+=1;}else{// start again from the topi=0;}}// should only be one token left, return itOk(tokens[0].as_num()?)}// string to token Vecfntokenize(s:&str)->Result<Vec<Token>,CalcError>{letmutret=Vec::new();forcins.split(' '){ret.push(Token::from_str(c)?);}Ok(ret)}fnmain(){letinput="2 / 2 + 3 * 4 - 6";assert_eq!(eval_str(input).unwrap(),7);}
Oh macro_rules are something I haven't dug into and explored much yet! Definitely used the built in ones, but haven't written any yet.
Thanks for the example!
I was intimidated by them for a while and avoided the topic - tried one once and now they even end up in my daily puzzle solutions :P Truly not complicated to use, and super handy!
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Rust, verbosely:
Oh macro_rules are something I haven't dug into and explored much yet! Definitely used the built in ones, but haven't written any yet.
Thanks for the example!
I was intimidated by them for a while and avoided the topic - tried one once and now they even end up in my daily puzzle solutions :P Truly not complicated to use, and super handy!