From<Type> as concrete type for trait Associated Type


#1

here is a simple example of using an Associated type in a trait:

trait Female{
    fn complain(&self) -> ();
}


trait Companion{
    type F: Female;
    fn get_comfort(&self, Self::F) -> ();
}

struct Cat{
    
}

impl Female for Cat{
    fn complain(&self) -> () {
        println!("it sucks to be a cat");
    }
}

struct Dog{

}

impl Companion for Dog{
    type F = Cat;

    fn get_comfort(&self, companion: Self::F) -> () {
        companion.complain();
    }
}


fn main(){
    let dog = Dog{};
    let cat = Cat{};
    dog.get_comfort(cat);
}

the other requirement i have is to make the Associated type a From trait, the reason being I need to pass a certain type of object (lets call it Foo) through a channel, and i want one of the traits methods to receive an object which can turn into Foo. so I end up with the following which isn’t allowed because i probably must put a concrete type as the Associated type. help?

trait Female{
    fn complain(&self) -> ();
}


trait Companion{
    type F: Female;
    fn get_comfort(&self, Self::F) -> ();
}

struct Cat{
    
}



struct Dog{

}

struct SuperCat{
    
}

impl Female for SuperCat{
    fn complain(&self) -> () {
        println!("it sucks to be a cat");
    }
}

impl From<Cat> for SuperCat{
    fn from(cat: Cat) -> Self {
        SuperCat{}
    }
}

impl Companion for Dog{
    **type F = From<Cat>;**

    fn get_comfort(&self, companion: Self::F) -> () {
        println("cant get this to work")
    }
}


fn main(){
    let dog = Dog{};
    let cat = Cat{};
    dog.get_comfort(cat);
}

#2

Perhaps the following setup will work for you (the rest of the code is as you have it):

trait Companion {
    type F: Female;
    
    // Take a generic type that can be turned into `Self::F`
    fn get_comfort<T: Into<Self::F>>(&self, T);
}

impl Companion for Dog {
    type F = SuperCat;

    fn get_comfort<T: Into<Self::F>>(&self, companion: T)  { }
}

fn main() {
    let dog = Dog {};
    let cat = Cat {};
    // Since there's a `From<Cat> for `SuperCat`, the below call is all good
    dog.get_comfort(cat);
}