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 move
d 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