• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Blightmud / Blightmud / 14316676040

07 Apr 2025 06:27PM UTC coverage: 74.417% (-0.9%) from 75.283%
14316676040

push

github

web-flow
Merge pull request #1202 from Blightmud/dependabot/cargo/rustls-0.23.25

build(deps): bump rustls from 0.23.23 to 0.23.25

7089 of 9526 relevant lines covered (74.42%)

431.56 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.48
/src/lua/mud.rs
1
use libmudtelnet::bytes::Bytes;
2
use mlua::{Function, Table, UserData, UserDataMethods};
3

4
use crate::{
5
    event::Event,
6
    model::{Connection, Line},
7
};
8

9
use super::{
10
    backend::Backend,
11
    constants::{
12
        BACKEND, IS_CONNECTED, MUD_INPUT_LISTENER_TABLE, MUD_OUTPUT_LISTENER_TABLE,
13
        ON_CONNECTION_CALLBACK_TABLE, ON_DISCONNECT_CALLBACK_TABLE,
14
    },
15
};
16

17
pub struct Mud {}
18

19
impl Mud {
20
    pub fn new() -> Self {
177✔
21
        Self {}
177✔
22
    }
177✔
23
}
24

25
impl UserData for Mud {
26
    fn add_methods<'lua, T: UserDataMethods<'lua, Self>>(methods: &mut T) {
177✔
27
        methods.add_function(
177✔
28
            "add_output_listener",
29
            |ctx, func: Function| -> mlua::Result<()> {
173✔
30
                let table: Table = ctx.named_registry_value(MUD_OUTPUT_LISTENER_TABLE)?;
173✔
31
                table.set(table.raw_len() + 1, func)?;
173✔
32
                Ok(())
173✔
33
            },
173✔
34
        );
35
        methods.add_function(
177✔
36
            "add_input_listener",
37
            |ctx, func: Function| -> mlua::Result<()> {
338✔
38
                let table: Table = ctx.named_registry_value(MUD_INPUT_LISTENER_TABLE)?;
338✔
39
                table.set(table.raw_len() + 1, func)?;
338✔
40
                Ok(())
338✔
41
            },
338✔
42
        );
43
        methods.add_function("output", |ctx, msg: String| {
177✔
44
            let backend: Backend = ctx.named_registry_value(BACKEND)?;
8✔
45
            backend
8✔
46
                .writer
8✔
47
                .send(Event::MudOutput(Line::from(msg)))
8✔
48
                .unwrap();
8✔
49
            Ok(())
8✔
50
        });
8✔
51
        methods.add_function(
177✔
52
            "connect",
53
            |ctx, (host, port, tls, verify): (String, u16, bool, Option<bool>)| {
16✔
54
                let backend: Backend = ctx.named_registry_value(BACKEND)?;
16✔
55
                let verify_cert = if tls { verify.unwrap_or(true) } else { false };
16✔
56
                backend
16✔
57
                    .writer
16✔
58
                    .send(Event::Connect(Connection {
16✔
59
                        host,
16✔
60
                        port,
16✔
61
                        tls,
16✔
62
                        verify_cert,
16✔
63
                    }))
16✔
64
                    .unwrap();
16✔
65
                Ok(())
16✔
66
            },
16✔
67
        );
68
        methods.add_function("disconnect", |ctx, ()| {
177✔
69
            let backend: Backend = ctx.named_registry_value(BACKEND)?;
38✔
70
            backend.writer.send(Event::Disconnect).unwrap();
38✔
71
            Ok(())
38✔
72
        });
38✔
73
        methods.add_function("reconnect", |ctx, ()| {
177✔
74
            let backend: Backend = ctx.named_registry_value(BACKEND)?;
15✔
75
            backend.writer.send(Event::Reconnect).unwrap();
15✔
76
            Ok(())
15✔
77
        });
15✔
78
        methods.add_function(
177✔
79
            "send",
80
            |ctx, (msg, options): (String, Option<mlua::Table>)| {
1✔
81
                let mut line = Line::from(msg);
1✔
82
                line.flags.bypass_script = true;
1✔
83
                line.flags.source = Some("script".to_string());
1✔
84

85
                if let Some(table) = options {
1✔
86
                    line.flags.gag = table.get("gag")?;
×
87
                    line.flags.skip_log = table.get("skip_log")?;
×
88
                }
1✔
89

90
                let backend: Backend = ctx.named_registry_value(BACKEND)?;
1✔
91
                backend.writer.send(Event::ServerInput(line)).unwrap();
1✔
92
                Ok(())
1✔
93
            },
1✔
94
        );
95
        methods.add_function("send_bytes", |ctx, bytes: Vec<u8>| {
177✔
96
            let backend: Backend = ctx.named_registry_value(BACKEND)?;
36✔
97
            backend
36✔
98
                .writer
36✔
99
                .send(Event::ServerSend(Bytes::from(bytes)))
36✔
100
                .unwrap();
36✔
101
            Ok(())
36✔
102
        });
36✔
103
        methods.add_function("input", |ctx, line: String| {
177✔
104
            let mut line = Line::from(line);
43✔
105
            line.flags.source = Some("script".to_string());
43✔
106
            let backend: Backend = ctx.named_registry_value(BACKEND)?;
43✔
107
            backend.writer.send(Event::ServerInput(line)).unwrap();
43✔
108
            Ok(())
43✔
109
        });
43✔
110
        methods.add_function("on_connect", |ctx, callback: mlua::Function| {
177✔
111
            let table: mlua::Table = ctx.named_registry_value(ON_CONNECTION_CALLBACK_TABLE)?;
34✔
112
            table.raw_set(table.raw_len() + 1, callback)?;
34✔
113
            Ok(())
34✔
114
        });
34✔
115
        methods.add_function("on_disconnect", |ctx, callback: mlua::Function| {
558✔
116
            let table: mlua::Table = ctx.named_registry_value(ON_DISCONNECT_CALLBACK_TABLE)?;
558✔
117
            table.set(table.raw_len() + 1, callback)?;
558✔
118
            Ok(())
558✔
119
        });
558✔
120
        methods.add_function("is_connected", |ctx, ()| {
177✔
121
            let value: bool = ctx.named_registry_value(IS_CONNECTED)?;
14✔
122
            Ok(value)
14✔
123
        });
14✔
124
        methods.add_function("add_tag", |ctx, tag: String| {
177✔
125
            let backend: Backend = ctx.named_registry_value(BACKEND)?;
15✔
126
            backend.writer.send(Event::AddTag(tag)).unwrap();
15✔
127
            Ok(())
15✔
128
        });
15✔
129
        methods.add_function("remove_tag", |ctx, tag: String| {
177✔
130
            let backend: Backend = ctx.named_registry_value(BACKEND)?;
×
131
            backend.writer.send(Event::RemoveTag(tag)).unwrap();
×
132
            Ok(())
×
133
        });
×
134
        methods.add_function("clear_tags", |ctx, ()| {
177✔
135
            let backend: Backend = ctx.named_registry_value(BACKEND)?;
×
136
            backend.writer.send(Event::ClearTags).unwrap();
×
137
            Ok(())
×
138
        });
×
139
    }
177✔
140
}
141

142
#[cfg(test)]
143
mod test_mud {
144
    use std::sync::mpsc::{channel, Receiver, Sender};
145

146
    use libmudtelnet::bytes::Bytes;
147
    use mlua::Lua;
148

149
    use crate::{
150
        event::Event,
151
        lua::constants::MUD_INPUT_LISTENER_TABLE,
152
        lua::constants::MUD_OUTPUT_LISTENER_TABLE,
153
        lua::{backend::Backend, constants::BACKEND},
154
        model::Connection,
155
        model::Line,
156
    };
157

158
    use super::Mud;
159

160
    #[test]
161
    fn test_output_register() {
1✔
162
        let mud = Mud::new();
1✔
163
        let lua = Lua::new();
1✔
164
        lua.set_named_registry_value(MUD_OUTPUT_LISTENER_TABLE, lua.create_table().unwrap())
1✔
165
            .unwrap();
1✔
166
        lua.globals().set("mud", mud).unwrap();
1✔
167
        lua.load("mud.add_output_listener(function () end)")
1✔
168
            .exec()
1✔
169
            .unwrap();
1✔
170
        let table: mlua::Table = lua.named_registry_value(MUD_OUTPUT_LISTENER_TABLE).unwrap();
1✔
171
        assert_eq!(table.raw_len(), 1);
1✔
172
    }
1✔
173

174
    #[test]
175
    fn test_input_register() {
1✔
176
        let mud = Mud::new();
1✔
177
        let lua = Lua::new();
1✔
178
        lua.set_named_registry_value(MUD_INPUT_LISTENER_TABLE, lua.create_table().unwrap())
1✔
179
            .unwrap();
1✔
180
        lua.globals().set("mud", mud).unwrap();
1✔
181
        lua.load("mud.add_input_listener(function () end)")
1✔
182
            .exec()
1✔
183
            .unwrap();
1✔
184
        let table: mlua::Table = lua.named_registry_value(MUD_INPUT_LISTENER_TABLE).unwrap();
1✔
185
        assert_eq!(table.raw_len(), 1);
1✔
186
    }
1✔
187

188
    fn assert_event(lua_code: &str, event: Event) {
9✔
189
        let (writer, reader): (Sender<Event>, Receiver<Event>) = channel();
9✔
190
        let backend = Backend::new(writer);
9✔
191
        let mud = Mud::new();
9✔
192
        let lua = Lua::new();
9✔
193
        lua.set_named_registry_value(BACKEND, backend).unwrap();
9✔
194
        lua.globals().set("mud", mud).unwrap();
9✔
195
        lua.load(lua_code).exec().unwrap();
9✔
196

9✔
197
        assert_eq!(reader.recv(), Ok(event));
9✔
198
    }
9✔
199

200
    #[test]
201
    fn test_connect() {
1✔
202
        assert_event(
1✔
203
            "mud.connect(\"hostname\", 99)",
1✔
204
            Event::Connect(Connection {
1✔
205
                host: "hostname".to_string(),
1✔
206
                port: 99,
1✔
207
                tls: false,
1✔
208
                verify_cert: false,
1✔
209
            }),
1✔
210
        );
1✔
211
        assert_event(
1✔
212
            "mud.connect(\"hostname\", 99, false)",
1✔
213
            Event::Connect(Connection {
1✔
214
                host: "hostname".to_string(),
1✔
215
                port: 99,
1✔
216
                tls: false,
1✔
217
                verify_cert: false,
1✔
218
            }),
1✔
219
        );
1✔
220
        assert_event(
1✔
221
            "mud.connect(\"hostname\", 99, true)",
1✔
222
            Event::Connect(Connection {
1✔
223
                host: "hostname".to_string(),
1✔
224
                port: 99,
1✔
225
                tls: true,
1✔
226
                verify_cert: true,
1✔
227
            }),
1✔
228
        );
1✔
229
        assert_event(
1✔
230
            "mud.connect(\"hostname\", 99, true, true)",
1✔
231
            Event::Connect(Connection {
1✔
232
                host: "hostname".to_string(),
1✔
233
                port: 99,
1✔
234
                tls: true,
1✔
235
                verify_cert: true,
1✔
236
            }),
1✔
237
        );
1✔
238
        assert_event(
1✔
239
            "mud.connect(\"hostname\", 99, true, false)",
1✔
240
            Event::Connect(Connection {
1✔
241
                host: "hostname".to_string(),
1✔
242
                port: 99,
1✔
243
                tls: true,
1✔
244
                verify_cert: false,
1✔
245
            }),
1✔
246
        );
1✔
247
    }
1✔
248

249
    #[test]
250
    fn test_default_disconnect() {
1✔
251
        assert_event("mud.disconnect()", Event::Disconnect);
1✔
252
    }
1✔
253

254
    #[test]
255
    fn test_disconnect() {
1✔
256
        let (writer, reader): (Sender<Event>, Receiver<Event>) = channel();
1✔
257
        let backend = Backend::new(writer);
1✔
258
        let mud = Mud::new();
1✔
259
        let lua = Lua::new();
1✔
260
        lua.set_named_registry_value(BACKEND, backend).unwrap();
1✔
261
        lua.globals().set("mud", mud).unwrap();
1✔
262
        lua.load("mud.disconnect()").exec().unwrap();
1✔
263
        assert_eq!(reader.recv().unwrap(), Event::Disconnect);
1✔
264
    }
1✔
265

266
    #[test]
267
    fn test_send_bytes() {
1✔
268
        assert_event(
1✔
269
            "mud.send_bytes({ 0xff, 0xf1 })",
1✔
270
            Event::ServerSend(Bytes::copy_from_slice(&[0xff, 0xf1])),
1✔
271
        );
1✔
272
    }
1✔
273

274
    #[test]
275
    fn test_mud_output_command() {
1✔
276
        let lua_code = r#"
1✔
277
        mud.output("test trigger")
1✔
278
        "#;
1✔
279
        assert_event(lua_code, Event::MudOutput(Line::from("test trigger")));
1✔
280
    }
1✔
281

282
    #[test]
283
    fn test_user_input_command() {
1✔
284
        let lua_code = r#"
1✔
285
        mud.input("test line")
1✔
286
        "#;
1✔
287

1✔
288
        assert_event(lua_code, Event::ServerInput(Line::from("test line")));
1✔
289
    }
1✔
290
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc