Skip to content

Commit

Permalink
added readLine function in stdio using a Buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
orpos committed Feb 20, 2025
1 parent 5d1401c commit 05fbc78
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 13 deletions.
30 changes: 19 additions & 11 deletions crates/lune-std-stdio/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
#![allow(clippy::cargo_common_metadata)]
use std::sync::LazyLock;

use lune_utils::fmt::{pretty_format_multi_value, ValueFormatConfig};
use mlua::prelude::*;
use mlua_luau_scheduler::LuaSpawnExt;

use tokio::io::{stderr, stdin, stdout, AsyncReadExt, AsyncWriteExt};
use tokio::io::{
stderr, stdin, stdout, AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, Stdin,
};

use lune_utils::TableBuilder;
use tokio::sync::Mutex;

mod prompt;
mod style_and_color;
Expand All @@ -18,6 +22,9 @@ const FORMAT_CONFIG: ValueFormatConfig = ValueFormatConfig::new()
.with_max_depth(4)
.with_colors_enabled(false);

static STDIN_BUFFER_READER: LazyLock<Mutex<BufReader<Stdin>>> =
LazyLock::new(|| Mutex::new(BufReader::new(stdin())));

/**
Creates the `stdio` standard library module.
Expand All @@ -33,6 +40,7 @@ pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
.with_async_function("write", stdio_write)?
.with_async_function("ewrite", stdio_ewrite)?
.with_async_function("readToEnd", stdio_read_to_end)?
.with_async_function("readLine", stdio_read_line)?
.with_async_function("prompt", stdio_prompt)?
.build_readonly()
}
Expand Down Expand Up @@ -63,21 +71,21 @@ async fn stdio_ewrite(_: &Lua, s: LuaString<'_>) -> LuaResult<()> {
Ok(())
}

/*
FUTURE: Figure out how to expose some kind of "readLine" function using a buffered reader.
This is a bit tricky since we would want to be able to use **both** readLine and readToEnd
in the same script, doing something like readLine, readLine, readToEnd from lua, and
having that capture the first two lines and then read the rest of the input.
*/

async fn stdio_read_to_end(lua: &Lua, (): ()) -> LuaResult<LuaString> {
let mut input = Vec::new();
let mut stdin = stdin();
stdin.read_to_end(&mut input).await?;
let mut buffer = STDIN_BUFFER_READER.lock().await;
buffer.get_mut().read_to_end(&mut input).await?;
lua.create_string(&input)
}

async fn stdio_read_line(lua: &Lua, (): ()) -> LuaResult<LuaString> {
let mut input = String::new();
let mut buffer = STDIN_BUFFER_READER.lock().await;
buffer.read_line(&mut input).await?;
let parsed = input.trim_end_matches('\n').trim_end_matches('\r');
lua.create_string(parsed)
}

async fn stdio_prompt(lua: &Lua, options: PromptOptions) -> LuaResult<PromptResult> {
lua.spawn_blocking(move || prompt(options))
.await
Expand Down
21 changes: 21 additions & 0 deletions tests/stdio/readLine.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
local stdio = require("@lune/stdio")

local function linePrefix(prefix:string)
print("-------")
stdio.write(prefix)
local t = stdio.readLine()
print("-------")
return t
end

local function toEndPrefix(prefix:string)
print("-------")
stdio.write(prefix)
local t = stdio.readToEnd()
print("-------")
return t
end

print(linePrefix("READLINE> "))
print(linePrefix("READLINE> "))
print(toEndPrefix("READTOEND> "))
18 changes: 16 additions & 2 deletions types/stdio.luau
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@ end
stdio.write("All on the same line")
stdio.ewrite("\nAnd some error text, too")
-- Reading the entire input from stdin
local input = stdio.readToEnd()
-- Reading from stdin, either line-by-line or the entire input
local firstLine = stdio.readLine()
local secondLine = stdio.readLine()
local remaining = stdio.readToEnd()
```
]=]
local stdio = {}
Expand Down Expand Up @@ -158,4 +160,16 @@ function stdio.readToEnd(): string
return nil :: any
end

--[=[
@within Stdio
@tag must_use
Reads a single line from stdin.
@return The input from stdin
]=]
function stdio.readLine(): string
return nil :: any
end

return stdio

0 comments on commit 05fbc78

Please sign in to comment.