Consume struct instance by returning a converted Vec<u8>

Hello,

That's me again !
And I feel stupid to come again, not founding solutions by myself... :cry:

I want to learn more about the language, and low level code.
So I have decided to implement SSH protocole following RFC.

But I have another problem...

Let's look at my code (you can get it on GitHub) :

In SshPacket, I have a into_bytes method that consume the instance and return a slice of u8.
And that slice is converted from a vector.
But the problem is that I can not return final_packet because of local owned references.
I have already try to clone the vector, or values gived to the vector, but it was non conclusive.

Here the cargo build error :

error[E0515]: cannot return value referencing local variable `final_packet`
  --> src\ssh\ssh_packet.rs:41:9
   |
41 |         &final_packet[..]
   |         ^------------^^^^
   |         ||
   |         |`final_packet` is borrowed here
   |         returns a value referencing data owned by the current function

Do you have any tips to correct that ? :thinking:

It's never possible to return a borrowed temporary reference to any newly created data. References are for giving permission to access data that already existed before the function call.

Change your function's return type to be Vec and not include any references anywhere (not a single & in the return type). And then keep cloning or calling .to_owned() until it matches that owning type.

2 Likes

As kornel said, just return the Vec you're making, remove the & and [..] here.

Hi and thanks for yours answers.

But that mean that the caller has the responsability to convert it ?
Is there a way to do a thing like I want ? Or I believe that the consumer will do it in the right way ?

To convert it to what? If they need &[u8], then, well, Vec<T> coerces to &[T] without any problem.

Yeah but the goal of this struct is to construct bytes buffer to send, so it must be a &[u8] no ?
Or I maybe missunderstand something ?

When they said "Vec<T> coerces to &[T]", they meant that...

fn main() {
    let buf: Vec<u8> = Vec::new();

    // You can do this
    let _slice: &[u8] = &buf;

    // Or this
    fn takes_a_slice(_: &[u8]) {}
    takes_a_slice(&buf);
}

Because the data in a Vec<T> and in a [T] are stored the same:

And because of Deref coercion.

1 Like

Ok, so if I understand the right way, it is like String and &str.
And so callers knows what they have to do with the vector.

Thanks for your precisions :slight_smile:

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.