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 }