I'm learning some Rust solving the Matasano Crypto Challenges and am stuck with implementing the Ceasar cipher ("single-byte xor") as an iterator. My function is supposed to look like this:
fn ceaser_cipher_iter(data: &Vec<u8>, key :u8) -> SomeType {
data.iter().map(move |&p| p^key)
}
Replacing SomeType with (), the compiler tells me what type it expects: core::iter::Map<core::slice::Iter<'_, u8>, [closure src/main.rs:59:21: 59:31]>. After some headbanging I found out I could use std::slice::Iter<u8> for core::slice::Iter<'_, u8>, which leaves the closure. As far as I understand, my naive experiment to use
fn ceaser_cipher_iter(data: &Vec<u8>, key :u8) -> Map<std::slice::Iter<u8>, fn(&u8)->u8 > {
data.iter().map(move |&p| p^key)
}
cannot work, because Rust needs to know the exact closure type to allocate the memory for the closure (key has to be stored by being moved into the closure). I've tried to follow the advice to use a Box instead:
fn ceaser_cipher_iter(data: &Vec<u8>, key :u8) -> Map<std::slice::Iter<u8>, Box<Fn(&u8)->u8> > {
data.iter().map(Box::new(move |&p| p^key))
}
But afaict map does not support it:
src/main.rs:59:17: 59:47 error: the trait `core::ops::FnMut<(&u8,)>` is not implemented for the type `Box<for<'r> core::ops::Fn(&'r u8) -> u8>` [E0277]
src/main.rs:59 data.iter().map(Box::new(move |&p| p^key))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:59:17: 59:47 error: the trait `core::ops::FnOnce<(&u8,)>` is not implemented for the type `Box<for<'r> core::ops::Fn(&'r u8) -> u8>` [E0277]
src/main.rs:59 data.iter().map(Box::new(move |&p| p^key))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Is there a way to return a map iterator with a closure?
The trick is not to box the closure, but the iterator as a whole.
fn ceaser_cipher_iter<'a>(data: &'a Vec<u8>, key: u8) -> Box<dyn Iterator<Item=u8> + 'a> {
Box::new(data.iter().map(move |&p| p.key))
}
Note that because the iterator uses a borrow, I had to add lifetime annotations so that the code would pass borrow checking.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With