exercises

Log | Files | Refs | README

main.rs (3167B)


      1 use creational_patterns::{
      2     builder::{Expression, SubExpression},
      3     calculator::{Calculator, CalculatorConfig},
      4     factory::{ScientificFactory, StandardFactory},
      5     number::StandardNumber,
      6     operator::{Operator, StandardOperator},
      7     token::Token,
      8 };
      9 
     10 fn main() -> Result<(), String> {
     11     // 1. Enum in Vec
     12     //
     13     // In Rust Vec has to be a single type, the Token enum conviniently allows
     14     // this by providing a unified type that can hold any token variant
     15     // let numbers = [
     16     //     Token::number(6.0),
     17     //     Token::operator(Operator::Add),
     18     //     Token::Number(3.0)
     19     // ]
     20 
     21     /// 2. Abstract Factory
     22     ///
     23     /// With the abstract factory pattern, we can create different kinds of
     24     /// calculators just by specifying which factory we would like to use:
     25     let standard_calc = Calculator::new(StandardFactory);
     26     let scientific_calc = Calculator::new(ScientificFactory);
     27 
     28     /// 3. Builder Pattern
     29     ///
     30     /// This is how the Builder Pattern and Abstract Factory Pattern compose:
     31     /// the builder delegates token creation to whichever factory it was given
     32     // With standard calculator factory
     33     let expr = Expression::builder(StandardFactory)
     34         .number("2")?
     35         .operator("+")?
     36         .open_paren()
     37         .number("3")?
     38         .operator("*")?
     39         .number("4")?
     40         .close_paren()?
     41         .build();
     42     // With scientific calculator factory
     43     let expr = Expression::builder(ScientificFactory)
     44         .number("1.23e-4")?
     45         .operator("sin")?
     46         .build()?;
     47 
     48     /// 3. Specialized Builder Pattern
     49     ///
     50     /// This encapsulate common expression patterns, so that we can write our
     51     /// expressions even more consicely
     52     let expr = Expression::builder(StandardFactory)
     53         .binary_op("2", "+", "3")?
     54         .build()?;
     55     let expr = Expression::builder(ScientificFactory)
     56         .function("sin", "0.5")?
     57         .build()?;
     58 
     59     /// 4. Prototype Pattern
     60     ///
     61     /// The quadratic_template method creates a prototype with placeholder
     62     /// coefficients. We can clone this template and modify the coefficients.
     63     let expr = Expression::quadratic_template(StandardFactory)?.build()?;
     64     let expr2 = expr.clone();
     65     expr2.set_coefficient(2, -4.0)?;
     66     /// The sub expression can be cloned and inserted into larger expressions
     67     let squared = SubExpression::new(
     68         vec![
     69             Token::variable("x".to_string()),
     70             Token::Operator(StandardOperator(Operator::Power)),
     71             Token::Number(StandardNumber(2.0)),
     72         ],
     73         StandardFactory,
     74     );
     75     /// prototype patterns that use Clone trait naturally:
     76     let expr1 = Expression::builder(StandardFactory)
     77         .extend(squared.clone().tokens)
     78         .operator("+")?
     79         .number("1")?
     80         .build()?;
     81     let expr2 = Expression::builder(StandardFactory)
     82         .number("2")?
     83         .operator("*")?
     84         .extend(squared.tokens)
     85         .build()?;
     86     /// use Default trait
     87     let default_calc = Calculator::new(StandardFactory);
     88     let scientific_calc =
     89         Calculator::with_config(ScientificFactory, CalculatorConfig::scientific());
     90 
     91     Ok(())
     92 }