命令行模式 Command

问题描述

代码示例

#![deny(
    warnings,
    clippy::all,
    clippy::cargo,
    clippy::nursery,
    clippy::pedantic
)]
#![allow(clippy::needless_pass_by_ref_mut)]

use std::cell::RefCell;
use std::rc::Rc;

/// The Receiver
pub struct Bulb {}

impl Bulb {
    pub fn turn_on(&mut self) {
        println!("Bulb has been lit");
    }

    pub fn turn_off(&mut self) {
        println!("Darkness!");
    }
}

pub type BulbNode = Rc<RefCell<Bulb>>;

pub trait Command {
    fn execute(&mut self);
    fn undo(&mut self);
    fn redo(&mut self);
}

pub struct TurnOn {
    bulb: BulbNode,
}

impl TurnOn {
    pub const fn new(bulb: BulbNode) -> Self {
        Self { bulb }
    }
}

impl Command for TurnOn {
    fn execute(&mut self) {
        self.bulb.borrow_mut().turn_on();
    }

    fn undo(&mut self) {
        self.bulb.borrow_mut().turn_off();
    }

    fn redo(&mut self) {
        self.execute();
    }
}

pub struct TurnOff {
    bulb: BulbNode,
}

impl TurnOff {
    #[must_use]
    pub const fn new(bulb: BulbNode) -> Self {
        Self { bulb }
    }
}

impl Command for TurnOff {
    fn execute(&mut self) {
        self.bulb.borrow_mut().turn_off();
    }

    fn undo(&mut self) {
        self.bulb.borrow_mut().turn_on();
    }

    fn redo(&mut self) {
        self.execute();
    }
}

/// The Invoker
pub struct RemoteControl {}

impl RemoteControl {
    pub fn submit(&self, command: &mut impl Command) {
        command.execute();
    }
}

fn main() {
    let bulb = Rc::new(RefCell::new(Bulb {}));
    let mut turn_on = TurnOn::new(bulb.clone());
    let mut turn_off = TurnOff::new(bulb);

    let remote = RemoteControl {};
    remote.submit(&mut turn_on);
    remote.submit(&mut turn_off);
}