| 
									
										
										
										
											2024-02-08 17:18:38 +01:00
										 |  |  | using System.Globalization; | 
					
						
							| 
									
										
										
										
											2024-02-08 23:06:16 +01:00
										 |  |  | using System.Text.Json.Serialization; | 
					
						
							| 
									
										
										
										
											2024-02-08 17:18:38 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace GrpcCalculator.Server; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-08 23:06:16 +01:00
										 |  |  | [JsonConverter(typeof(JsonStringEnumConverter))] | 
					
						
							| 
									
										
										
										
											2024-02-08 17:18:38 +01:00
										 |  |  | public enum CalculatorState | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     AfterEquals, | 
					
						
							|  |  |  |     AfterOperator, | 
					
						
							|  |  |  |     AfterDigit, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-08 23:06:16 +01:00
										 |  |  | [JsonConverter(typeof(JsonStringEnumConverter))] | 
					
						
							| 
									
										
										
										
											2024-02-08 17:18:38 +01:00
										 |  |  | public enum CalculatorOperator | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Addition, | 
					
						
							|  |  |  |     Subtraction, | 
					
						
							|  |  |  |     Multiplication, | 
					
						
							|  |  |  |     Division, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public static class CalculatorOperatorMethods | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     public static string Evaluate(this CalculatorOperator op, string leftOperand, string rightOperand) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         var leftOperandValue = double.Parse(leftOperand); | 
					
						
							|  |  |  |         var rightOperandValue = double.Parse(rightOperand); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return op switch | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             CalculatorOperator.Addition => (leftOperandValue + rightOperandValue).ToString(CultureInfo.InvariantCulture), | 
					
						
							|  |  |  |             CalculatorOperator.Subtraction => (leftOperandValue - rightOperandValue).ToString(CultureInfo.InvariantCulture), | 
					
						
							|  |  |  |             CalculatorOperator.Multiplication => (leftOperandValue * rightOperandValue).ToString(CultureInfo.InvariantCulture), | 
					
						
							|  |  |  |             CalculatorOperator.Division => (leftOperandValue / rightOperandValue).ToString(CultureInfo.InvariantCulture), | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public record Calculator(CalculatorState State, string LeftOperand, CalculatorOperator? Operator, string RightOperand) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     private string Evaluate() => Operator.HasValue switch { | 
					
						
							|  |  |  |         true => Operator.Value.Evaluate(LeftOperand, RightOperand), | 
					
						
							|  |  |  |         false => RightOperand, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public Calculator() : this(CalculatorState.AfterEquals, "0", null, "0") { } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-08 18:19:48 +01:00
										 |  |  |     public Calculator OperatorPressed(CalculatorOperator op) => new( | 
					
						
							|  |  |  |         LeftOperand: State switch { | 
					
						
							|  |  |  |             CalculatorState.AfterOperator or CalculatorState.AfterEquals => Display, | 
					
						
							| 
									
										
										
										
											2024-02-08 17:18:38 +01:00
										 |  |  |             CalculatorState.AfterDigit => Evaluate(), | 
					
						
							| 
									
										
										
										
											2024-02-08 18:19:48 +01:00
										 |  |  |         },  | 
					
						
							|  |  |  |         Operator: op,  | 
					
						
							|  |  |  |         RightOperand: Display,  | 
					
						
							|  |  |  |         State: CalculatorState.AfterOperator); | 
					
						
							| 
									
										
										
										
											2024-02-08 17:18:38 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     public Calculator EqualsPressed() => this with { | 
					
						
							|  |  |  |         LeftOperand = Evaluate(), | 
					
						
							|  |  |  |         State = CalculatorState.AfterEquals, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public Calculator DigitPressed(string digit) => this with { | 
					
						
							|  |  |  |         LeftOperand = State switch { | 
					
						
							| 
									
										
										
										
											2024-02-08 18:19:48 +01:00
										 |  |  |             CalculatorState.AfterEquals or CalculatorState.AfterOperator => Display, | 
					
						
							| 
									
										
										
										
											2024-02-08 17:18:38 +01:00
										 |  |  |             CalculatorState.AfterDigit => LeftOperand, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         RightOperand = State switch { | 
					
						
							|  |  |  |             CalculatorState.AfterOperator or CalculatorState.AfterEquals => digit, | 
					
						
							|  |  |  |             CalculatorState.AfterDigit => RightOperand + digit, | 
					
						
							| 
									
										
										
										
											2024-02-08 18:19:48 +01:00
										 |  |  |         }, | 
					
						
							| 
									
										
										
										
											2024-02-08 17:18:38 +01:00
										 |  |  |         State = CalculatorState.AfterDigit, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public string Display => | 
					
						
							|  |  |  |         State switch | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             CalculatorState.AfterDigit => RightOperand, | 
					
						
							|  |  |  |             CalculatorState.AfterOperator or CalculatorState.AfterEquals => LeftOperand, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | } |