4ntoine
4ntoine

Reputation: 20420

What's the common API for both `Vec<String>` and flatbuffers' vector of String in Rust?

I'd like to be able to iterate over Rust vector of String (Vec<String>) and flatbuffers' vector of strings: IDL as follows:

table Sitekeys {
  domains: [string];
}

Here is how the file is generated (with flatc --rust ...):

  #[inline]
  pub fn domains(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<&'a str>>> {
    ...
  }

I can't figure the signature of the function that can accept both vectors. I believe it should be the most base possible interface (trait in Rust). Coming from J2EE/Android i think about smth similar to java.util.List or java.util.Iterator.

What would be the suitable signature in Rust?

PS. Obviously i can extract some new common interface with adapter for each case, but i'd prefer to operate with just base interface.

PPS. I forgot to mention that performance matters, so i'd prefer to avoid creating of new instances (if it's used behind the scenes in into_iter() or smth) if possible.

Upvotes: 1

Views: 728

Answers (1)

Netwave
Netwave

Reputation: 42716

flatbuffers::Vector does not implement AsRef<[T]> but it does implement IntoIterator, so you can make your function signature use that.

fn take_iterator<'a>(iter: impl IntoIterator<Item=&'a str>) {}

Also, your flatbuffer object actually uses &str not String, you can match both and use a Vec<&str>:

fn main() {
    let flatbuffer_v: flatbuffers::Vector<flatbuffers::ForwardsUOffset<&str>> = flatbuffers::Vector::default();
    let std_v: Vec<&str> = Vec::new();
    take_iterator(flatbuffer_v);
    take_iterator(std_v);
}

or, if you have a Vec<String> just take the references:

fn main() {
    let flatbuffer_v: flatbuffers::Vector<flatbuffers::ForwardsUOffset<&str>> = flatbuffers::Vector::default();
    let std_v: Vec<String> = Vec::new();
    take_iterator(flatbuffer_v);
    take_iterator(std_v.iter().map(AsRef::as_ref));
}

Upvotes: 2

Related Questions