enum/
enum.rs

1// Copyright 2019 Andrew Thomas Christensen
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the
4// MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option. This file may not be copied,
5// modified, or distributed except according to those terms.
6
7// NOTE: This example is the same as the "Activity" example (examples/activity.rs), except that it uses a concrete type
8// (an enum) to represent all states of the Automaton, as opposed to using a separate struct for each state.
9
10use mode::{Automaton, Family, Mode};
11
12struct ActivityFamily;
13
14impl Family for ActivityFamily {
15    type Base = Activity;
16    type Mode = Activity;
17}
18
19#[derive(Copy, Clone)]
20enum Activity {
21    Working { hours_worked : u32 },
22    Eating { hours_worked : u32, calories_consumed : u32 },
23    Sleeping { hours_rested : u32 },
24}
25
26impl Mode for Activity {
27    type Family = ActivityFamily;
28}
29
30impl Activity {
31    pub fn update(mut self) -> Self {
32        match self {
33            Activity::Working{ ref mut hours_worked } => {
34                println!("Work, work, work...");
35                *hours_worked += 1;
36                if *hours_worked == 4 || *hours_worked >= 8 {
37                    println!("Time for {}!", if *hours_worked == 4 { "lunch" } else { "dinner" });
38                    Activity::Eating { hours_worked: *hours_worked, calories_consumed: 0 }
39                }
40                else { self }
41            },
42            Activity::Eating { hours_worked, ref mut calories_consumed } => {
43                println!("Yum!");
44                *calories_consumed += 100;
45                if *calories_consumed >= 500 {
46                    if hours_worked >= 8 {
47                        println!("Time for bed!");
48                        Activity::Sleeping { hours_rested: 0 }
49                    }
50                    else {
51                        println!("Time to go back to work!");
52                        Activity::Working { hours_worked }
53                    }
54                }
55                else { self }
56            },
57            Activity::Sleeping { ref mut hours_rested } => {
58                println!("ZzZzZzZz...");
59                *hours_rested += 1;
60                if *hours_rested >= 8 {
61                    println!("Time for breakfast!");
62                    Activity::Eating { hours_worked: 0, calories_consumed: 0 }
63                }
64                else { self }
65            },
66        }
67    }
68}
69
70fn main() {
71    let mut person = ActivityFamily::automaton_with_mode(Activity::Working { hours_worked: 0 });
72    
73    for _age in 18..100 {
74        // Update the current Mode and swap other Modes in, as needed.
75        Automaton::next(&mut person, |current_mode| current_mode.update());
76    }
77}