to fix this use case you can use the fact that function pointers are Copy, like so :
pub fn my_atoi(s: &str) -> i32 {
struct Processor(fn(&mut Processor, c: char, a: i32) -> i32);
fn processor_sign(out : &mut Processor, c: char, a: i32) -> i32 {
match c {
' ' => a,
'+' => {*out = Processor(processor_digit_positive); a},
'-' => {*out = Processor(processor_digit_negative); a},
'0' .. '9' => {*out = Processor(processor_digit_positive); processor_digit_positive(out, c,0)},
_ => {*out = Processor(processor_end); a}
};
a
};
fn processor_digit_positive(out : &mut Processor, c: char, a: i32) -> i32 {
match c {
'0' .. '9' => a.saturating_mul(10).saturating_add(c.to_digit(10).unwrap() as i32),
_ => {*out = Processor(processor_end); a}
}
};
fn processor_digit_negative(out : &mut Processor, c: char, a: i32) -> i32 {
match c {
'0' .. '9' => a.saturating_mul(10).saturating_sub(c.to_digit(10).unwrap() as i32),
_ => {*out = Processor(processor_end); a}
}
};
fn processor_end(out : &mut Processor, c:char, a:i32) -> i32 {
panic!();
}
let (mut p, mut r) = (Processor(processor_sign), 0);
for c in s.chars() {
r = p.0(&mut p,c, r);
if p.0 == processor_end {
return r;
}
}
return r;
}
but it would be much better to not have processor_end at all, as well as to pass the result by mutable reference.
pub fn my_atoi(s: &str) -> i32 {
struct Processor(Option<fn(&mut Processor, char, &mut i32)>);
fn processor_sign(out : &mut Processor, c: char, a: &mut i32) {
match c {
' ' => {},
'+' => *out = Processor(Some(processor_digit_positive)),
'-' => *out = Processor(Some(processor_digit_negative)),
'0' .. '9' => {*out = Processor(Some(processor_digit_positive)); processor_digit_positive(out, c,a)},
_ => *out = Processor(None)
}
};
fn processor_digit_positive(out : &mut Processor, c: char, a: &mut i32) {
match c {
'0' .. '9' => *a = a.saturating_mul(10).saturating_add(c.to_digit(10).unwrap() as i32),
_ => *out = Processor(None)
}
};
fn processor_digit_negative(out : &mut Processor, c: char, a: &mut i32) {
match c {
'0' .. '9' => *a = a.saturating_mul(10).saturating_sub(c.to_digit(10).unwrap() as i32),
_ => *out = Processor(None)
}
};
let (mut p, mut r) = (Processor(Some(processor_sign)), 0);
for c in s.chars() {
if let Some(process) = p.0 {
process(&mut p, c, &mut r)
} else {
return r
}
}
return r;
}