You cannot use the HStream type directly; it doesn't represent anything. It's only used to construct derived pointer types, such as &HStream and Box<HStream>.
The simplest solution would be to have a LinkedList of Stream<Box<HStream>>.
fn main() {
let mut list = Arc::new(Mutex::new(LinkedList::<Stream<Box<HStream>>>::new()));
}
Then, we just have to implement HStream for Box<HStream>.
impl<'a> HRecv for Box<HStream + 'a> {}
impl<'a> HSend for Box<HStream + 'a> {}
impl<'a> AsRawFd for Box<HStream + 'a> {
fn as_raw_fd(&self) -> RawFd { (&**self).as_raw_fd() }
}
impl<'a> HStream for Box<HStream + 'a> {}
Note that this is missing a trait... Clone.
Clone is not object-safe, which means that it's not possible to create trait object types for that trait, such as &Clone or Box<Clone>. Clone is not object-safe because its clone method returns Self, which represents the concrete type of the implementor. If you used this method through a trait object, the compiler wouldn't be able to know in advance the type of the result (it could be any of Clone's implementors!).
Since HStream is a subtrait of Clone, HStream is not object-safe either. The consequence is that we can't implement Clone at all, and types like Box<HStream> are not legal to use.
However, we can work around this by making our own, object-safe trait. We can even automatically implement it on types that implement the standard Clone trait.
pub trait BoxedHStreamClone {
fn boxed_clone(&self) -> Box<HStream>;
}
// Implementation for all types that implement HStream and Clone and don't hold any borrows
impl<T: HStream + Clone + 'static> BoxedHStreamClone for T {
fn boxed_clone(&self) -> Box<HStream> {
Box::new(self.clone()) as Box<HStream>
}
}
// Implementation for Box<HStream + 'a>, which cannot implement Clone
impl<'a> BoxedHStreamClone for Box<HStream + 'a> {
fn boxed_clone(&self) -> Box<HStream> {
Box::new((&**self).boxed_clone()) as Box<HStream>
}
}
Replace the Clone trait bound on HStream with BoxedHStreamClone and you're good to go!
pub trait HStream: HRecv + HSend + AsRawFd + BoxedHStreamClone {}
Here's the final code:
use std::sync::{Arc, Mutex};
use std::collections::LinkedList;
use std::os::unix::io::{RawFd, AsRawFd};
pub trait BoxedHStreamClone {
fn boxed_clone(&self) -> Box<HStream>;
}
impl<T: HStream + Clone + 'static> BoxedHStreamClone for T {
fn boxed_clone(&self) -> Box<HStream> {
Box::new(self.clone()) as Box<HStream>
}
}
pub trait HRecv {}
pub trait HSend {}
pub trait HStream: HRecv + HSend + AsRawFd + BoxedHStreamClone {}
pub struct Stream<T: HStream> {
pub inner: T
}
pub type StreamList = Arc<Mutex<LinkedList<Stream<Box<HStream>>>>>;
impl<'a> HRecv for Box<HStream + 'a> {}
impl<'a> HSend for Box<HStream + 'a> {}
impl<'a> AsRawFd for Box<HStream + 'a> {
fn as_raw_fd(&self) -> RawFd { (&**self).as_raw_fd() }
}
impl<'a> BoxedHStreamClone for Box<HStream + 'a> {
fn boxed_clone(&self) -> Box<HStream> {
Box::new((&**self).boxed_clone()) as Box<HStream>
}
}
impl<'a> HStream for Box<HStream + 'a> {}
fn main() {
let mut list = Arc::new(Mutex::new(LinkedList::<Stream<Box<HStream>>>::new()));
}