use std::ops::DerefMut;
trait Action {
type Target: ?Sized;
fn run(self, target: &mut Self::Target);
}
struct SayPersonName;
impl Action for SayPersonName {
type Target = Person;
fn run(self, target: &mut Self::Target) {
println!("{}", target.name());
}
}
trait Person {
fn name(&self) -> &String;
}
struct Hero {
name: String,
}
impl Hero {
fn run<A, T>(&mut self, action: A)
where A: Action<Target = T>,
Hero: DerefMut<Target = T>
{ // Here It fails to compile
action.run(self);
}
}
impl Person for Hero {
fn name(&self) -> &String {
&self.name
}
}
fn main() {
let mut hero = Hero { name: String::from("My hero") };
let action = SayPersonName;
hero.run(action);
}
Is this what you're trying to do?
trait Action {
type Target: ?Sized;
fn run(self, target: &mut Self::Target);
}
struct SayPersonName;
impl Action for SayPersonName {
type Target = Person;
fn run(self, target: &mut Self::Target) {
println!("{}", target.name());
}
}
trait Person {
fn name(&self) -> &String;
}
struct Hero {
name: String,
}
impl Hero {
fn run<A>(&mut self, action: A) where A: Action<Target=Person> {
action.run(self);
}
}
impl Person for Hero {
fn name(&self) -> &String {
&self.name
}
}
fn main() {
let mut hero = Hero { name: String::from("My hero") };
let action = SayPersonName;
hero.run(action);
}
No. I want to pass two different actions those accept different traits those are implemented by Hero.
Oh, right, sorry... I think you want something like this:
#![feature(unsize)]
use std::marker::Unsize;
trait Action {
type Target: ?Sized;
fn run(self, target: &mut Self::Target);
}
struct SayPersonName;
impl Action for SayPersonName {
type Target = Person;
fn run(self, target: &mut Self::Target) {
println!("{}", target.name());
}
}
trait Person {
fn name(&self) -> &String;
}
struct Hero {
name: String,
}
impl Hero {
fn run<A, T:?Sized>(&mut self, action: A)
where A: Action<Target = T>,
Hero: Unsize<T>
{
action.run(self);
}
}
impl Person for Hero {
fn name(&self) -> &String {
&self.name
}
}
fn main() {
let mut hero = Hero { name: String::from("My hero") };
let action = SayPersonName;
hero.run::<SayPersonName, Person>(action);
}
I did not check out yet. But it seems promising. Thanks.