Skip to content

Instantly share code, notes, and snippets.

@henninglive
Created June 18, 2017 20:05
Show Gist options
  • Select an option

  • Save henninglive/a77e02738d71780ca8bdbb43587e3239 to your computer and use it in GitHub Desktop.

Select an option

Save henninglive/a77e02738d71780ca8bdbb43587e3239 to your computer and use it in GitHub Desktop.
Command Pattern
trait Command<T> {
type Err;
fn forward(&mut self, receiver: &mut T) -> Result<(), Self::Err>;
fn backwards(&mut self, receiver: &mut T) -> Result<(), Self::Err>;
}
struct CommandStack<T, C: Command<T>>{
stack: Vec<C>,
receiver: T,
}
impl<T, C: Command<T>> CommandStack<T, C> {
fn new(receiver: T) -> CommandStack<T, C> {
CommandStack {
stack: Vec::new(),
receiver: receiver,
}
}
fn push(&mut self, mut command: C) -> Result<(), C::Err> {
command.forward(&mut self.receiver)?;
self.stack.push(command);
Ok(())
}
fn pop(&mut self) -> Option<Result<C, C::Err>> {
let mut c = match self.stack.pop() {
Some(c) => c,
None => return None,
};
match c.backwards(&mut self.receiver) {
Ok(_) => Some(Ok(c)),
Err(e) => {
self.stack.push(c);
Some(Err(e))
}
}
}
}
use std::any::Any;
use std::error::Error;
trait CommandDyn<T>: Any {
fn forward(&mut self, receiver: &mut T) -> Result<(), Box<Error>>;
fn backwards(&mut self, receiver: &mut T) -> Result<(), Box<Error>>;
}
struct CommandStackDyn<T>{
stack: Vec<Box<CommandDyn<T>>>,
receiver: T,
}
impl<T> CommandStackDyn<T> {
fn new(receiver: T) -> CommandStackDyn<T> {
CommandStackDyn {
stack: Vec::new(),
receiver: receiver,
}
}
fn push<C: CommandDyn<T>>(&mut self, mut command: C)
-> Result<(), Box<Error>>
{
command.forward(&mut self.receiver)?;
self.stack.push(Box::new(command));
Ok(())
}
fn pop(&mut self) -> Option<Result<Box<CommandDyn<T>>, Box<Error>>> {
let mut c = match self.stack.pop() {
Some(c) => c,
None => return None,
};
match c.backwards(&mut self.receiver) {
Ok(_) => Some(Ok(c)),
Err(e) => {
self.stack.push(c);
Some(Err(e))
}
}
}
}
fn main() {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment