Dynamic Submission in Rust

In something that I'm working on, I have a data warehouse object and a set of operations that can be applied to this data warehouse. I would like to be able to easily expand the set of operations and create alternative data warehouse implementations. Inspired by the modifier box , I tried to apply its approach, in essence, create a trait for an abstract (store, operation) pair, and then implement this for each specific pair.

Unfortunately, I cannot figure out how to bind the implementations of a particular pair to an abstract setting. Here is the “minimal” version of what I'm trying to do:

use std::fmt::Debug;

trait Target: Debug {}
impl<T: Target + ?Sized> Target for Box<T> {}

trait Weapon: Debug {}
impl<W: Weapon + ?Sized> Weapon for Box<W> {}

trait AttackStrategy<T: Target> {
    fn attack(&self, &T);
}

impl<T: Target, S: AttackStrategy<T> + ?Sized> AttackStrategy<T> for Box<S> {
    fn attack(&self, enemy: &T) {
        &self.attack(enemy);
    }
}

trait Attack {
    fn attack_with<S: AttackStrategy<Self>>(&self, strategy: &S) where Self: Target + Sized {
        strategy.attack(self);
    }
}

impl<T: Target> Attack for T {}

#[derive(Debug)]
struct Zombie(i32);
impl Target for Zombie {}

#[derive(Debug)]
struct Bunny(i32);
impl Target for Bunny {}

#[derive(Debug)]
struct BaseballBat(i32);
impl Weapon for BaseballBat {}

#[derive(Debug)]
struct Knife(i32);
impl Weapon for Knife {}

impl AttackStrategy<Zombie> for BaseballBat {
    fn attack(&self, zed: &Zombie) {
        println!("Attacking {:?} with {:?}! Whack whack whack! Whew. That was close!", zed, self);
    }
}

impl AttackStrategy<Bunny> for BaseballBat {
    fn attack(&self, hopper: &Bunny) {
        println!("Attacking {:?} with {:?}! Swoosh swoosh swoosh! Dang, he got away!", hopper, self);
    }
}

impl AttackStrategy<Zombie> for Knife {
    fn attack(&self, zed: &Zombie) {
        println!("Attacking {:?} with {:?}! Stick stick stick! Oh no! He bit me!", zed, self);
    }
}

impl AttackStrategy<Bunny> for Knife {
    fn attack(&self, hopper: &Bunny) {
        println!("Attacking {:?} with {:?}! Stick stick stick! Yum! Dinner!", hopper, self);
    }
}

#[allow(dead_code)]
fn main() {
    let louisville_slugger = BaseballBat(5);
    let rabbit = Bunny(-1);
    rabbit.attack_with(&louisville_slugger);

    let cleaver: Box<Weapon> = Box::new(Knife(2));
    let brains_seeker = Zombie(17);
    brains_seeker.attack_with(&cleaver);
}

Error with error:

test.rs:75:19: 75:40 error: the trait `AttackStrategy<Zombie>` is not implemented for the type `Weapon` [E0277]
test.rs:75     brains_seeker.attack_with(&cleaver);
                             ^~~~~~~~~~~~~~~~~~~~~

Can someone suggest a better way to do this or a way to resolve this error?

+4
1

, Weapon AttackStrategy<_> impl Target. , attack_with ( , , ) - Haskell, Rust .

, , ( ++, ).

+1

Source: https://habr.com/ru/post/1605870/


All Articles