Issue with undeclared lifetimes

#1

Hi,
I’m trying to write bindings for the Virustotal API. It accepts a list of hashes to be rescaned.
My initial idea was to specify that the parameter passed should be able to be formed into in an Vec<&str>

Sine rustc told me to there should be an explicit lifetime name I added the 'static lifetime resulting in Vec<&static str>

But since I would like to accept hashes which are not backed into the binary I tried to replace the 'static lifetime with 'a lifetime.

Unfortunately now I get the error that the lifetime is undeclared.

It would be awesome if someone here could guide me in the right direction :slight_smile:

Playground Link

pub fn rescan_hashes<T: Into<Vec<&'a str>>>(
  api_key: &str,
  hash: T,
) -> Result<Vec<RescanResponse>, VTError> {
  let hash: Vec<&str> = hash.into();
  let hashes = hash.join(",");
  let hash_ref = hashes.as_str();
  let mut params = std::collections::HashMap::new();
  params.insert("apikey", &api_key);
  params.insert("resource", &hash_ref);
  let req = reqwest::Client::new();
  let req = req
    .post("https://www.virustotal.com/vtapi/v2/file/rescan")
    .form(&params)
    .send();
[...]
}
#2

Is there a specific reason your vector is holding string slices? If it is acceptable, Vec<String> will be much easier to write.

e: Playground

3 Likes
#3

Thanks @parasyte. I thought it might be best to accept the least specific type as parameter

#4

You can make it work with &str by declaring a lifetime parameter:

pub fn rescan_hashes<'a, T: Into<Vec<&'a str>>>(...)

Whether you should do that depends on what types you intend to use here.

1 Like
#5

Also, should mention that you don’t need to necessarily make this decision in rescan_hashes - you can allow the caller to decide if they want to give you owned string or borrowed slices. Something like:

use std::borrow::Borrow;

pub fn rescan_hashes(api_key: &str, hash: &[impl Borrow<str>]) 
   -> Result<Vec<RescanResponse>, VTError> {
  let hashes = hash.join(",");
  let hash_ref = hashes.as_str();
  ...
}

There’s also no (seeming) reason to use Into here - just have the caller give you a slice to begin with since rescan_hashes always materializes the slice anyway, and it’s likely your callers will already have something they can obtain a slice from (e.g. Vec, array, etc).

1 Like