Is there a way to improve this container abstraction example?

Function two_funny_numbers wants to produce a pair of some box-like instances, function i_want_two wants to receive numbers in some wrappers.

Can this example be improved somehow? For example, can main omit repetition of types container types?

use std::rc::Rc;
use std::sync::Arc;


trait LikeContainer<T> {
   type Container;
   
   fn allocate(x:T) -> Self::Container;
   fn read<'a>(c : Self::Container) -> T;
}

impl<T> LikeContainer<T> for Rc<T> where T : Copy{
    type Container = Rc<T>;
    fn allocate(x:T) -> Self::Container {
        Rc::new(x)
    }
    fn read<'a>(c : Self::Container) -> T {
        *c
    }
}

impl<T> LikeContainer<T> for Arc<T> where T : Copy{
    type Container = Arc<T>;
    fn allocate(x:T) -> Self::Container {
        Arc::new(x)
    }
    fn read<'a>(c : Self::Container) -> T {
        *c
    }
}

impl<T> LikeContainer<T> for Box<T> where T : Copy{
    type Container = Box<T>;
    fn allocate(x:T) -> Self::Container {
        Box::new(x)
    }
    fn read<'a>(c : Self::Container) -> T {
        *c
    }
}



fn two_funny_numbers<Q> () -> (Q::Container, Q::Container)
        where Q : LikeContainer<u8>
{
    (Q::allocate(69), Q::allocate(37))
}

fn i_want_two<Q> ( a : (Q::Container, Q::Container)) 
        where Q : LikeContainer<u8> 
{
    println!("{} {}", Q::read(a.0), Q::read(a.1));
}



fn main() {
    i_want_two::<Rc<u8>> (two_funny_numbers::<Rc <u8>>());
    i_want_two::<Arc<u8>>(two_funny_numbers::<Arc<u8>>());
    i_want_two::<Box<u8>>(two_funny_numbers::<Box<u8>>());

    //let a : (Rc<u8>, Rc<u8>);
    //a = two_funny_numbers();
    //i_want_two(a);
}

Playpen link: Rust Playground

I think Self::Container is not needed, and you can just use Self instead. That should improve type inference.

Also, I think read should be a &self method, not taking the container by value?