Skip to content

Commit 306bf82

Browse files
committed
Added Interpreter
1 parent 5537069 commit 306bf82

File tree

6 files changed

+104
-2
lines changed

6 files changed

+104
-2
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ version = "0.1.0"
44
edition = "2021"
55

66
[dependencies]
7+
regex = "1"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Decorator | Structural | ✅ | [Wiki](https://en.wikipedia.org
2121
Facade | Structural | ✅ | [Wiki](https://en.wikipedia.org/wiki/Facade_pattern) |
2222
Factory Method | Creational | ✅ | [Wiki](https://en.wikipedia.org/wiki/Factory_method_pattern) |
2323
Flyweight | Structural | ✅ | [Wiki](https://en.wikipedia.org/wiki/Flyweight_pattern) |
24-
Interpreter | Behavioral | | [Wiki](https://en.wikipedia.org/wiki/Interpreter_pattern) |
24+
Interpreter | Behavioral | | [Wiki](https://en.wikipedia.org/wiki/Interpreter_pattern) |
2525
Iterator | Behavioral | ⏳ | [Wiki](https://en.wikipedia.org/wiki/Iterator_pattern) |
2626
Mediator | Behavioral | ⏳ | [Wiki](https://en.wikipedia.org/wiki/Mediator_pattern) |
2727
Memento | Behavioral | ⏳ | [Wiki](https://en.wikipedia.org/wiki/Memento_pattern) |
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use std::error::Error;
2+
use design_patterns::behavioral::interpreter::shop_assistant::Order;
3+
4+
fn main() -> Result<(), Box<dyn Error>> {
5+
let order = Order::parse("order x100 'pack of toothpicks' from Tesco")?;
6+
println!("{:#?}", order);
7+
8+
let order = Order::parse("order x5 'pack of milk' from Macro")?;
9+
println!("{:#?}", order);
10+
11+
Ok(())
12+
}

src/behavioral/interpreter/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//! # Interpreter
2+
//!
3+
//! ## Type
4+
//!
5+
//! Behavioral
6+
//!
7+
//! ## Description
8+
//!
9+
//! In computer programming, the interpreter pattern is a design pattern that
10+
//! specifies how to evaluate sentences in a language. The basic idea is to
11+
//! have a class for each symbol (terminal or nonterminal) in a specialized
12+
//! computer language. The syntax tree of a sentence in the language is an
13+
//! instance of the composite pattern and is used to evaluate (interpret) the
14+
//! sentence for a client.
15+
16+
pub mod shop_assistant;
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use regex::Regex;
2+
use std::error::Error;
3+
4+
#[derive(Debug, PartialEq)]
5+
pub struct Order {
6+
pub qty: u32,
7+
pub product: String,
8+
pub source: String,
9+
}
10+
11+
impl Order {
12+
pub fn new<S: Into<String>>(qty: u32, product: S, source: S) -> Self {
13+
Self {
14+
qty,
15+
product: product.into(),
16+
source: source.into(),
17+
}
18+
}
19+
20+
pub fn parse<S: Into<String>>(command: S) -> Result<Self, Box<dyn Error>> {
21+
// Grammar Representationconst
22+
let optional_space = " ?";
23+
let qty = String::from("x(?P<qty>\\d+)") + optional_space;
24+
let product = String::from("'(?P<product>[\\w ]+)'") + optional_space;
25+
let source = "from (?P<source>\\w+)";
26+
let order_command =
27+
String::from("order") + optional_space + qty.as_str() + product.as_str() + source;
28+
29+
let re = Regex::new(&order_command)?;
30+
let command = command.into();
31+
let x = re.captures(command.as_ref()).ok_or("Bad command")?;
32+
33+
Ok(Self {
34+
product: x
35+
.name("product")
36+
.ok_or("Product not defined")?
37+
.as_str()
38+
.to_string(),
39+
qty: x.name("qty").ok_or("Qty not defined")?.as_str().parse()?,
40+
source: x
41+
.name("source")
42+
.ok_or("Source not defined")?
43+
.as_str()
44+
.to_string(),
45+
})
46+
}
47+
}
48+
49+
impl Default for Order {
50+
fn default() -> Self {
51+
Self::new(1, "Ice cream", "Five")
52+
}
53+
}
54+
55+
#[cfg(test)]
56+
mod tests {
57+
use super::Order;
58+
59+
#[test]
60+
fn test_1() {
61+
let order = Order::new(12, "1L milk packs", "Macro");
62+
let command = "order x12 '1L milk packs' from Macro";
63+
assert_eq!(order, Order::parse(command).unwrap());
64+
}
65+
66+
#[test]
67+
fn test_2() {
68+
let order = Order::new(1, "a bag of potatoes", "Tesco");
69+
let command = "order x1 'a bag of potatoes' from Tesco";
70+
assert_eq!(order, Order::parse(command).unwrap());
71+
}
72+
}

src/behavioral/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//!
55
//! 1. [Chain of Responsibility](chain_of_responsibility)
66
//! 1. [Command](command)
7-
//! 1. Interpreter
7+
//! 1. [Interpreter](interpreter)
88
//! 1. Iterator
99
//! 1. Mediator
1010
//! 1. Memento
@@ -16,3 +16,4 @@
1616
1717
pub mod chain_of_responsibility;
1818
pub mod command;
19+
pub mod interpreter;

0 commit comments

Comments
 (0)