actix_lua/
builder.rs

1use std::fs::File;
2use std::io::prelude::*;
3
4use crate::actor::LuaActor;
5use rlua::{Error as LuaError, Lua};
6
7/// `LuaActorBuilder` creates a new `LuaActor` with given Lua script.
8pub struct LuaActorBuilder {
9    started: Option<String>,
10    handle: Option<String>,
11    stopped: Option<String>,
12}
13
14impl Default for LuaActorBuilder {
15    fn default() -> LuaActorBuilder {
16        let noop = Some("return".to_string());
17        LuaActorBuilder {
18            started: noop.clone(),
19            handle: noop.clone(),
20            stopped: noop.clone(),
21        }
22    }
23}
24
25impl LuaActorBuilder {
26    /// Initialize a new `LuaActorBuilder`
27    pub fn new() -> Self {
28        LuaActorBuilder::default()
29    }
30
31    /// create a `started` hook with given lua file
32    pub fn on_started(mut self, filename: &str) -> Self {
33        self.started = Some(read_to_string(filename));
34        self
35    }
36
37    /// create a `started` hook with given lua script
38    pub fn on_started_with_lua(mut self, script: &str) -> Self {
39        self.started = Some(script.to_string());
40        self
41    }
42
43    /// handle message with given lua file
44    pub fn on_handle(mut self, filename: &str) -> Self {
45        self.handle = Some(read_to_string(filename));
46        self
47    }
48
49    /// handle message with given lua script
50    pub fn on_handle_with_lua(mut self, script: &str) -> Self {
51        self.handle = Some(script.to_string());
52        self
53    }
54
55    /// create a `stopped` hook with given lua file.
56    pub fn on_stopped(mut self, filename: &str) -> Self {
57        self.stopped = Some(read_to_string(filename));
58        self
59    }
60
61    /// create a `stopped` hook with given lua script
62    pub fn on_stopped_with_lua(mut self, script: &str) -> Self {
63        self.stopped = Some(script.to_string());
64        self
65    }
66
67    /// build the actor with a preconfigured lua VM
68    ///
69    /// It's important to use the `rlua` interface exported by `actix-lua` with `use actix_lua::dev::rlua::*`
70    pub fn build_with_vm(self, vm: Lua) -> Result<LuaActor, LuaError> {
71        LuaActor::new_with_vm(
72            vm,
73            self.started.clone(),
74            self.handle.clone(),
75            self.stopped.clone(),
76        )
77    }
78
79    /// build the actor
80    pub fn build(self) -> Result<LuaActor, LuaError> {
81        LuaActor::new(
82            self.started.clone(),
83            self.handle.clone(),
84            self.stopped.clone(),
85        )
86    }
87}
88
89fn read_to_string(filename: &str) -> String {
90    let mut f = File::open(filename).expect("File not found");
91    let mut body = String::new();
92    f.read_to_string(&mut body).expect("Failed to read file");
93
94    body
95}
96
97#[cfg(test)]
98mod tests {
99    use super::*;
100    use std::mem::discriminant;
101
102    #[test]
103    fn build_script_error() {
104        let res = LuaActorBuilder::new()
105            .on_handle_with_lua(r"return 1 +")
106            .build();
107
108        if let Err(e) = res {
109            assert_eq!(
110                discriminant(&LuaError::RuntimeError("unexpected symbol".to_string())),
111                discriminant(&e)
112            );
113        // ok
114        } else {
115            panic!("should return error");
116        }
117    }
118
119}