1#![allow(clippy::cargo_common_metadata)]
2
3use lune_utils::fmt::{pretty_format_multi_value, ValueFormatConfig};
4use mlua::prelude::*;
5use mlua_luau_scheduler::LuaSpawnExt;
6
7use tokio::io::{stderr, stdin, stdout, AsyncReadExt, AsyncWriteExt};
8
9use lune_utils::TableBuilder;
10
11mod prompt;
12mod style_and_color;
13
14use self::prompt::{prompt, PromptOptions, PromptResult};
15use self::style_and_color::{ColorKind, StyleKind};
16
17const FORMAT_CONFIG: ValueFormatConfig = ValueFormatConfig::new()
18 .with_max_depth(4)
19 .with_colors_enabled(false);
20
21pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
29 TableBuilder::new(lua)?
30 .with_function("color", stdio_color)?
31 .with_function("style", stdio_style)?
32 .with_function("format", stdio_format)?
33 .with_async_function("write", stdio_write)?
34 .with_async_function("ewrite", stdio_ewrite)?
35 .with_async_function("readToEnd", stdio_read_to_end)?
36 .with_async_function("prompt", stdio_prompt)?
37 .build_readonly()
38}
39
40fn stdio_color(lua: &Lua, color: ColorKind) -> LuaResult<LuaValue> {
41 color.ansi_escape_sequence().into_lua(lua)
42}
43
44fn stdio_style(lua: &Lua, style: StyleKind) -> LuaResult<LuaValue> {
45 style.ansi_escape_sequence().into_lua(lua)
46}
47
48fn stdio_format(_: &Lua, args: LuaMultiValue) -> LuaResult<String> {
49 Ok(pretty_format_multi_value(&args, &FORMAT_CONFIG))
50}
51
52async fn stdio_write(_: &Lua, s: LuaString<'_>) -> LuaResult<()> {
53 let mut stdout = stdout();
54 stdout.write_all(s.as_bytes()).await?;
55 stdout.flush().await?;
56 Ok(())
57}
58
59async fn stdio_ewrite(_: &Lua, s: LuaString<'_>) -> LuaResult<()> {
60 let mut stderr = stderr();
61 stderr.write_all(s.as_bytes()).await?;
62 stderr.flush().await?;
63 Ok(())
64}
65
66async fn stdio_read_to_end(lua: &Lua, (): ()) -> LuaResult<LuaString> {
75 let mut input = Vec::new();
76 let mut stdin = stdin();
77 stdin.read_to_end(&mut input).await?;
78 lua.create_string(&input)
79}
80
81async fn stdio_prompt(lua: &Lua, options: PromptOptions) -> LuaResult<PromptResult> {
82 lua.spawn_blocking(move || prompt(options))
83 .await
84 .into_lua_err()
85}