LimitedFifoQueue
is a struct that wraps the functionality of a VecDeque
to limit the number of items it will store at any time:
use std::collections::{vec_deque, VecDeque};
use std::fmt;
use std;
#[derive(Debug)]
pub struct LimitedFifoQueue<T> {
size: usize,
store: VecDeque<T>,
}
impl<T> LimitedFifoQueue<T> where T: fmt::Display {
pub fn new(size: usize) -> LimitedFifoQueue<T> {
LimitedFifoQueue {
size: size,
store: VecDeque::with_capacity(size),
}
}
pub fn push(&mut self, elem: T) {
self.store.push_front(elem);
if self.store.len() > self.size {
self.store.pop_back();
}
}
pub fn clear(&mut self) {
self.store.clear();
}
}
I've implemented the IntoIterator
trait as follows:
impl<T> IntoIterator for LimitedFifoQueue<T> where T: fmt::Display {
type Item = T;
type IntoIter = vec_deque::IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.store.into_iter()
}
}
And a simplified function that loops through and prints each Item:
fn print_all<I>(lines: &I) where I: IntoIterator {
for string in lines.into_iter() {
println!("{}", string);
}
}
This gives me the following error:
println!("{}", string);
^^^^^^ the trait `std::fmt::Display` is not implemented for `<I as std::iter::IntoIterator>::Item`
I have created a playground of the code with a full stack trace here.
Also, I'm aware that there may be a better way to accomplish what I'm trying to do. I'd love to hear any additional suggestions.
How can I implement
std::fmt::Display
for a customIntoIterator::Item
?
You cannot. Item
might be a type you don't own, and Display
is a trait you don't own. You cannot implement a trait you don't own for a type you don't own.
All you can do is require that Item
implements Display
:
fn print_all<I>(lines: I)
where I: IntoIterator,
I::Item: fmt::Display,
{
for string in lines.into_iter() {
println!("{}", string);
}
}
You don't need any of the other T: Display
bounds on your data structure or its methods, as none of those implementations care to print out a value.
Incidentally, into_iter
is automatically called on the for-loops argument, so you only need to say:
fn print_all<I>(lines: I)
where I: IntoIterator,
I::Item: fmt::Display,
{
for string in lines {
println!("{}", string);
}
}
You may also wish to review How to implement Iterator and IntoIterator for a simple struct?, as you are passing &lfq
into print_all
, but &LimitedFifoQueue
doesn't implement IntoIterator
, only LimitedFifoQueue
does. These are different types. You'll need something like
impl<'a, T> IntoIterator for &'a LimitedFifoQueue<T> {
type Item = &'a T;
type IntoIter = vec_deque::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.store.iter()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With