I have a rather weird case where I need to return a option of a vec, both inside a struct, and just as as the option.
I made a small example here, which looks silly, but it’s the same issue I have in a setting where it makes more sense (in the real world, the container represents a state to compute a next function, while the output option is a output to the user of my api)
pub struct Container {
opt : Option<Vec<u8>>
}
pub fn return_option(plaintext: Vec<u8>) -> Option<Vec<u8>> {
match plaintext.len() {
l if l > 5 => None,
_ => Some(plaintext)
}
}
pub fn return_stuff(plaintext: Vec<u8>) -> (Container,Option<Vec<u8>>) {
let dummycontainer = return_option(plaintext);
return (Container{
opt : dummycontainer.clone(),
},
dummycontainer)
}
So, the return_stuff, is the important one, in order not to have the compiler complain about the dummycontainer being a moved value.
In order to get around this, I clone the option, which sounds like an antipattern to me.
Is there any way around doing this, while still passing the options two different places?
EDIT
borrowing with a static lifetime seems to be the best route.
I just have no idea how. Trying to write the struct like this:
pub struct Container {
opt : Option<&'a [u8]>
}
Is not allowed, and neither is:
pub fn return_stuff(plaintext: Vec<u8>) -> (Container,Option<&'a [u8]>) {
>Solution :
Assuming someone else owns the Vec<u8> and everything you’re talking about is strictly read-only, we can do the entire thing with slices. The original value can still be a Vec<u8>, but we’re never passing ownership of that to any of the functions mentioned here.
pub struct Container<'a> {
opt : Option<&'a [u8]>
}
pub fn return_option<'a>(plaintext: &'a [u8]) -> Option<&'a [u8]> {
match plaintext.len() {
l if l > 5 => None,
_ => Some(plaintext)
}
}
pub fn return_stuff<'a>(plaintext: &'a [u8]) -> (Container<'a>,Option<&'a [u8]>) {
let dummycontainer = return_option(plaintext);
return (
Container{
opt: dummycontainer,
},
dummycontainer,
)
}
If you’ve got a vector my_vec, you call these functions by borrowing it, as return_stuff(&my_vec[..]).