0

So I have a struct with a new method that makes a HTTP request and returns part of the response, which should deserialize into the struct that this method is for. The problem I'm having is that the part of the response I need is contained within a Vec<> in the response and using .first() gives a reference to it.

I tried dereferencing it, but my struct needs to have the Copy trait. So then I derived that, but my struct contains a field with a Vec<> type, and that needs to have the Copy trait. I learned about the error I was getting a bit and found out that references always have the Copy trait, so I should be able to just make my field &'a Vec<>. At this point I'm getting into named lifetimes territory, which I'm not very familiar with, being fairly new to Rust. It still doesn't work though, because:

error[E0277]: the trait bound `&'a Vec<f32>: Deserialize<'_>` is not satisfied
    --> src/embeddings.rs:26:14
     |
26   |     pub vec: &'a Vec<f32>,
     |              ^^^^^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `&'a Vec<f32>`
     |

And now I'm stuck. Here's hopefully enough of my code to find a solution:

#[derive(Deserialize)]
struct NewEmbeddingRequestResponse<'a> {
    data: Vec<Embedding<'a>>,
}

#[derive(Deserialize, Clone, Copy)]
pub struct Embedding<'a> {
    /* ... */
    pub vec: &'a Vec<f32>,
}

impl<'a> Embedding<'a> {
    pub async fn new(/* ... */) -> Result<Embedding<'a>, reqwest::Error> {
        /* ... */

        let response: NewEmbeddingRequestResponse = client.post(/* ... */)
            /* ... */
            .send().await?.json().await?;

        let embedding = *response.data.first().unwrap();

        Ok(embedding)
    }
}
  • *"The problem I'm having is that the part of the response I need is a reference"* - you should back up, revisit this problem, and explain a bit more. It looks like trying to make your type implement `Copy` as brought you down the wrong path. Presenting the original problem is a good way to avoid bad solutions from chasing [XY-problems](https://en.wikipedia.org/wiki/XY_problem). It does not look like `response` is a reference at all; does the issue stem from `.first()`? – kmdreko Dec 28 '22 at 03:07
  • I should have phrased it better- `response` is not a reference, you're right, `.first()` returns a reference to the struct I need, and I assumed that there wasn't a way to get a non-reference to it from the `Vec<>` in `response`. I'll edit my question to clarify a bit. – valentinegb Dec 28 '22 at 03:10
  • Perfect! In that case, does this resolve your question? [How can I take an item from a Vec?](/q/45803990/2189130) In general `.remove(0)` or `.swap_remove(0)` (more efficient if you don't care about order) is the way to get ownership of an element. Though if you're specifically getting the first element and throwing the rest away, `.into_iter().next().unwrap()` might be best. – kmdreko Dec 28 '22 at 03:22
  • That works, thank you! I think I learned a valuable lesson about taking it back a step and addressing the root of the problem haha – valentinegb Dec 28 '22 at 03:26

0 Answers0