Hi everyone !
Currently I am working on my zip
function, which should return iterator and I want it to accept both &str and String without extra allocations, so it should use Cow under the hood. The function:
pub fn zip<'a, S>(
labels: &'a [S],
values: &'a [S],
) -> impl Iterator<Item=impl Iterator<Item=(S, S)> + 'a>
where
S: Into<Cow<'a, str>>
{
values
.chunks(labels.len())
.map(move |chunk| {
chunk
.iter()
.zip(labels.iter())
.map(|(&l, &v)| (l.into(), v.into()))
})
}
But I got an error when try to compile the code:
error[E0271]: expected `{closure@main.rs:16:22}` to be a closure that returns `(S, S)`, but it returns `(Cow<'_, str>, Cow<'_, str>)`
--> src/main.rs:6:25
|
3 | pub fn zip<'a, S>(
| - expected this type parameter
...
6 | ) -> impl Iterator<Item=impl Iterator<Item=(S, S)> + 'a>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(S, S)`, found `(Cow<'_, str>, Cow<'_, str>)`
|
= note: expected tuple `(S, S)`
found tuple `(Cow<'_, str>, Cow<'_, str>)`
= note: required for `Map<Zip<Iter<'_, S>, Iter<'_, S>>, {closure@main.rs:16:22}>` to implement `Iterator`
Sandbox: Rust Playground
Am I using the generics wrong in such way ?
Could somebody explain the error and help me to fix the function ?
P.S. why I need this function. I have a Modal (I implementing it for ratatui-rs). And I want it to be universal for any input (input will be in the form Vec<Vec<(&str, &str)>>
), and I want to avoid extra allocations such as using vectors, or using .clone()/.to_string()/.to_owned() etc.
The iterator which zip
function return I want to use to build Vec<List>
, where List
is a component from ratatui-rs.
Example of input:
I receive characters: Vec<Object>, where each Object { guid: u64, name: String }
I want my Modal to draw list of items in the form "Name: <CharName> -- Guid: <CharGuid>"