daily pastebin goal
70%
SHARE
TWEET

Untitled

a guest Mar 14th, 2018 60 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. use std::sync::{Arc, Mutex};
  2.  
  3. trait Command {
  4.     type E;
  5.     fn execute(&self) -> Result<(), Self::E>;
  6.     fn undo(&self) -> Result<(), Self::E>;
  7. }
  8.  
  9. struct Reciever {
  10.     count: u32
  11. }
  12.  
  13. impl Reciever {
  14.     fn new() -> Self {
  15.         Reciever {
  16.             count: 0
  17.         }
  18.     }
  19.     fn increment(&mut self) -> Result<(), String> {
  20.         let prev = self.count;
  21.         self.count = self.count.saturating_add(1);
  22.         if prev==self.count {
  23.             return Err("Counter overflow".into());
  24.         }
  25.         Ok(())
  26.     }
  27.     fn decrement(&mut self) -> Result<(), String> {
  28.         let prev = self.count;
  29.         self.count = self.count.saturating_sub(1);
  30.         if prev==self.count {
  31.             return Err("Counter underflow".into());
  32.         }
  33.         Ok(())
  34.     }
  35. }
  36.  
  37. struct IncreaseCommand {
  38.     reciever: Arc<Mutex<Reciever>>
  39. }
  40.  
  41. impl Command for IncreaseCommand {
  42.     type E = String;
  43.     fn execute(&self) -> Result<(), Self::E> {
  44.         let mut inner = self.reciever.lock().unwrap();
  45.         inner.increment()
  46.     }
  47.     fn undo(&self) -> Result<(), Self::E> {
  48.         let mut inner = self.reciever.lock().unwrap();
  49.         inner.decrement()
  50.     }
  51. }
  52.  
  53. struct Invoker {
  54.     commands: Vec<Box<Command<E=String>>>,
  55.     next: usize,
  56. }
  57.  
  58. impl Invoker {
  59.     fn new() -> Self {
  60.         Invoker {
  61.             commands: Vec::new(),
  62.             next: 0
  63.         }
  64.     }
  65.     fn push_command(&mut self, c: Box<Command<E=String>>) {
  66.         self.commands.push(c);
  67.     }
  68.     fn do_next(&mut self) -> Result<(), String> {
  69.         if self.next >= self.commands.len() {
  70.             return Err("No next command available".into());
  71.         }
  72.         self.next += 1;
  73.         self.commands[self.next-1].execute()
  74.     }
  75.     fn undo_prev(&mut self) -> Result<(), String> {
  76.         if self.next == 0 {
  77.             return Err("No previous command available".into());
  78.         }
  79.         self.next -= 1;
  80.         self.commands[self.next].undo()
  81.     }
  82. }
  83.  
  84. fn main() {
  85.     let counterA = Arc::new(Mutex::new(Reciever::new()));
  86.     let counterB = Arc::new(Mutex::new(Reciever::new()));
  87.     let mut invoker = Invoker::new();
  88.     invoker.push_command(Box::new(IncreaseCommand{reciever: counterA.clone()}));
  89.     invoker.push_command(Box::new(IncreaseCommand{reciever: counterA.clone()}));
  90.     invoker.push_command(Box::new(IncreaseCommand{reciever: counterB.clone()}));
  91.     invoker.push_command(Box::new(IncreaseCommand{reciever: counterA.clone()}));
  92.     invoker.push_command(Box::new(IncreaseCommand{reciever: counterB.clone()}));
  93.     println!("A: {}", counterA.lock().unwrap().count);
  94.     println!("B: {}", counterB.lock().unwrap().count);
  95.     for _ in 0..invoker.commands.len() {
  96.         invoker.do_next().unwrap();
  97.         println!("A: {}", counterA.lock().unwrap().count);
  98.         println!("B: {}", counterB.lock().unwrap().count);
  99.     }
  100.     for _ in 0..invoker.commands.len() {
  101.         invoker.undo_prev().unwrap();
  102.         println!("A: {}", counterA.lock().unwrap().count);
  103.         println!("B: {}", counterB.lock().unwrap().count);
  104.     }
  105. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top