exercises

Log | Files | Refs | README

main.rs (1557B)


      1 use std::collections::HashMap;
      2 
      3 use structural_patterns::{
      4     BinaryOperation, CachingExpression, ConsoleLogger, Expression, LoggingExpression,
      5     NumberExpression, Operator, TimingExpression,
      6 };
      7 
      8 fn main() -> Result<(), String> {
      9     /// Structural Patterns
     10     ///
     11     /// 1. Decorator Pattern
     12     let expr = Box::new(NumberExpression::new(42.0));
     13     let cached = Box::new(CachingExpression::new(expr));
     14     let timed = Box::new(TimingExpression::new(cached));
     15     let logged = LoggingExpression::new(timed, Box::new(ConsoleLogger));
     16     // When evaluate is called on the outermost decorator, the call flows through
     17     // each layer. The order of wrapping matters.
     18     let result = logged.evaluate(&HashMap::new());
     19 
     20     /// 2. Composite Pattern
     21     /// Because all nodes implement Expression, Decorator Pattern work seamlessly
     22     /// with Composite Pattern trees.
     23     /// The tree structure encodes operator precedence directly:
     24     let multiply = Box::new(BinaryOperation::new(
     25         Box::new(NumberExpression::new(3.0)),
     26         Box::new(NumberExpression::new(4.0)),
     27         Operator::Multiply,
     28     ));
     29     let add = Box::new(BinaryOperation::new(
     30         Box::new(NumberExpression::new(2.0)),
     31         multiply,
     32         Operator::Add,
     33     ));
     34     /// Evaluating the tree is a single method call:
     35     let variables = HashMap::new();
     36     println!("Expression: {}", add.to_string());
     37     match add.evaluate(&variables) {
     38         Ok(result) => println!("Result: {}", result),
     39         Err(error) => eprintln!("Error: {}", error),
     40     }
     41 
     42     Ok(())
     43 }