Skip to content

Commit e2dd64d

Browse files
committed
Memento: "classic" and serde implementations
1 parent e4c0e92 commit e2dd64d

File tree

5 files changed

+145
-0
lines changed

5 files changed

+145
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ members = [
2020
"behavioral/command",
2121
"behavioral/iterator",
2222
"behavioral/mediator",
23+
"behavioral/memento",
2324
]

behavioral/memento/Cargo.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
edition = "2021"
3+
name = "memento"
4+
version = "0.1.0"
5+
6+
[[bin]]
7+
name = "memento"
8+
path = "classic.rs"
9+
10+
[[bin]]
11+
name = "memento-serde"
12+
path = "serde.rs"
13+
14+
[dependencies]
15+
serde = {version = "1.0", features = ["derive"]}
16+
serde_json = "1.0"

behavioral/memento/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Memento
2+
3+
## `classic.rs`
4+
5+
A conceptual example of Memento pattern.
6+
7+
```bash
8+
cargo run --bin memento
9+
```
10+
11+
Output:
12+
13+
```
14+
Originator backup: '1'
15+
Originator backup: '2'
16+
Restored to state: 2
17+
Restored to state: 1
18+
```
19+
20+
## `serde.rs`
21+
22+
A Memento example implemented via serialization with `serde` crate which is pretty popular in Rust.
23+
24+
```bash
25+
cargo run --bin memento-serde
26+
```
27+
28+
Output:
29+
30+
```
31+
{"state":1}
32+
{"state":2}
33+
Restored to state: 2
34+
Restored to state: 1
35+
```

behavioral/memento/classic.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
trait Memento<T> {
2+
fn restore(self) -> T;
3+
fn print(&self);
4+
}
5+
6+
struct Originator {
7+
state: u32,
8+
}
9+
10+
impl Originator {
11+
pub fn save(&self) -> OriginatorBackup {
12+
OriginatorBackup {
13+
state: self.state.to_string(),
14+
}
15+
}
16+
}
17+
18+
struct OriginatorBackup {
19+
state: String,
20+
}
21+
22+
impl Memento<Originator> for OriginatorBackup {
23+
fn restore(self) -> Originator {
24+
Originator {
25+
state: self.state.parse().unwrap(),
26+
}
27+
}
28+
29+
fn print(&self) {
30+
println!("Originator backup: '{}'", self.state);
31+
}
32+
}
33+
34+
fn main() {
35+
let mut history = Vec::<OriginatorBackup>::new();
36+
37+
let mut originator = Originator { state: 0 };
38+
39+
originator.state = 1;
40+
history.push(originator.save());
41+
42+
originator.state = 2;
43+
history.push(originator.save());
44+
45+
for moment in history.iter() {
46+
moment.print();
47+
}
48+
49+
let originator = history.pop().unwrap().restore();
50+
println!("Restored to state: {}", originator.state);
51+
52+
let originator = history.pop().unwrap().restore();
53+
println!("Restored to state: {}", originator.state);
54+
}

behavioral/memento/serde.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
use serde::{Serialize, Deserialize};
3+
4+
#[derive(Serialize, Deserialize)]
5+
struct Originator {
6+
state: u32,
7+
}
8+
9+
impl Originator {
10+
pub fn save(&self) -> String {
11+
serde_json::to_string(self).unwrap()
12+
}
13+
14+
pub fn restore(json: &str) -> Self {
15+
serde_json::from_str(json).unwrap()
16+
}
17+
}
18+
19+
fn main() {
20+
let mut history = Vec::<String>::new();
21+
22+
let mut originator = Originator { state: 0 };
23+
24+
originator.state = 1;
25+
history.push(originator.save());
26+
27+
originator.state = 2;
28+
history.push(originator.save());
29+
30+
for moment in history.iter() {
31+
println!("{}", moment);
32+
}
33+
34+
let originator = Originator::restore(&history.pop().unwrap());
35+
println!("Restored to state: {}", originator.state);
36+
37+
let originator = Originator::restore(&history.pop().unwrap());
38+
println!("Restored to state: {}", originator.state);
39+
}

0 commit comments

Comments
 (0)