well first i would strongly recommend against doing rust on leetcode.
their horrible exercises are easily recognizable with the stupide impl Solution, and they always use the wrongest type possible.
if you were to ever write an atoi, it should be my_atoi(&str) -> i32, not String.
to see an example, you can look at str::parse, which is the correct function for doing that in std.
i would personally recommend exercism, but there may be others that are just as good.
secondly, the answer is not with closures. you have come back to one of the original issue you had in your previous post ; you can't have a reference to the function inside the Parser while modifyng it at the same time.
that is why i said last time
but closures are not all copy. why have you decided to use closures exactly ? there is no need, you do not capture any context.
simply using function pointers again fixes it, and removes the unnecessary and wasteful boxing.
struct Parser(Option<fn(&mut Parser, char, &mut i32)>);
fn parse_sign(parser: &mut Parser, c: char, a: &mut i32) {
fn accu(c: char, a: &mut i32, f: fn(i32, i32) -> i32) {
*a = f(a.saturating_mul(10), c.to_digit(10).unwrap() as i32)
}
fn process_digit(parser: &mut Parser, c: char, a: &mut i32, f: fn(i32, i32) -> i32) {
match c {
'0' ..= '9' => accu(c, a, f),
_ => *parser = Parser(None),
}
}
match c {
c if c.is_whitespace() => (),
'+' => *parser = Parser(Some(|parser: &mut Parser, c: char, a: &mut i32| process_digit(parser, c, a, i32::saturating_add))),
'-' => *parser = Parser(Some(|parser: &mut Parser, c: char, a: &mut i32| process_digit(parser, c, a, i32::saturating_sub))),
'0' ..= '9' => {
*parser = Parser(Some(|parser: &mut Parser, c: char, a: &mut i32| process_digit(parser, c, a, i32::saturating_add)));
accu(c, a, i32::saturating_add)
},
_ => *parser = Parser(None),
}
}
struct Solution;
impl Solution {
pub fn my_atoi(s: String) -> i32 {
let (mut parser, mut a) = (Parser(Some(parse_sign)), 0);
for c in s.chars() {
match parser.0 {
Some(f) => f(&mut parser, c, &mut a),
None => return a,
}
}
return a;
}
}