I got it to work with a few edits! Thanks:
use std::sync::Arc;
use tokio::sync::Mutex;
use async_trait::async_trait;
pub trait CloneAnimal {
fn clone_animal<'s>(&self) -> Arc<Mutex<dyn Animal + 's>> where Self: 's;
}
impl<T: Clone + Animal> CloneAnimal for T {
fn clone_animal<'s>(&self) -> Arc<Mutex<dyn Animal + 's>> where Self: 's {
Arc::new(Mutex::new(self.clone()))
}
}
#[async_trait]
pub trait AsyncCloneAnimal {
async fn async_clone<'s>(&self) -> Arc<Mutex<dyn Animal + 's>> where Self: 's;
}
#[async_trait]
impl<T: ?Sized + CloneAnimal + std::marker::Send> AsyncCloneAnimal for Arc<Mutex<T>> {
async fn async_clone<'s>(&self) -> Arc<Mutex<dyn Animal + 's>> where Self: 's {
(*(self.lock().await)).clone_animal()
}
}
// -----
// Added supertrait bound
#[async_trait]
pub trait Animal: CloneAnimal + Send {
fn new() -> Self where Self: Sized;
fn set_name(&mut self, name: String);
fn get_name(&self) -> String;
}
// Added derive
#[derive(Clone)]
pub struct Cat {
name: String,
}
impl Animal for Cat {
fn new() -> Self {
Cat {
name: "".to_string(),
}
}
fn set_name(&mut self, name: String) {
self.name = name;
}
fn get_name(&self) -> String {
self.name.to_string()
}
}
#[tokio::main]
async fn main() {
let mut animal : Cat = Animal::new();
animal.set_name("Garfield".into());
println!("Original name: {}", animal.name);
let animal = Arc::new(Mutex::new(animal));
func1(animal.async_clone().await).await;
func2(animal.async_clone().await).await;
}
pub async fn func1(animal: Arc<Mutex<dyn Animal>>) {
let clone = animal.async_clone().await;
let mut guard = animal.lock().await;
guard.set_name("Foobar".into());
println!("After change: {}", guard.get_name());
}
pub async fn func2(animal: Arc<Mutex<dyn Animal>>) {
let clone = animal.async_clone().await;
let guard = clone.lock().await;
// Check if still Garfield.
println!("Still Garfield? {}. No...", guard.get_name());
}
pub async fn func3() {
// Only way to make a new instance seems to create it manually.
let mut animal : Cat = Animal::new();
animal.set_name("Garfield".into());
}
Could you elaborate bit on your answer please?