mirror of
https://github.com/lune-org/lune.git
synced 2024-12-12 13:00:37 +00:00
Migrate console global to stdio
This commit is contained in:
parent
420a861061
commit
bbf1c9f4f7
19 changed files with 435 additions and 299 deletions
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -7,14 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added a new global `stdio` which replaces `console` and adds a couple new functions:
|
||||||
|
- `write` writes a string directly to stdout, without any newlines
|
||||||
|
- `ewrite` writes a string directly to stderr, without any newlines
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- Migrated `console.setColor/resetColor` and `console.setStyle/resetStyle` to `stdio.color` and `stdio.style` to allow for more flexibility in custom printing using ANSI color codes. Check the documentation for new usage and behavior.
|
||||||
- Migrated the pretty-printing and formatting behavior of `console.log/info/warn/error` to the standard Luau printing functions.
|
- Migrated the pretty-printing and formatting behavior of `console.log/info/warn/error` to the standard Luau printing functions.
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
- Removed printing functions `console.log/info/warn/error` in favor of regular global functions for printing.
|
- Removed printing functions `console.log/info/warn/error` in favor of regular global functions for printing.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed scripts hanging indefinitely on error
|
||||||
|
|
||||||
## `0.2.2` - February 5th, 2023
|
## `0.2.2` - February 5th, 2023
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
33
Cargo.lock
generated
33
Cargo.lock
generated
|
@ -117,6 +117,19 @@ dependencies = [
|
||||||
"os_str_bytes",
|
"os_str_bytes",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "console"
|
||||||
|
version = "0.15.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60"
|
||||||
|
dependencies = [
|
||||||
|
"encode_unicode",
|
||||||
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
|
"unicode-width",
|
||||||
|
"windows-sys 0.42.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "convert_case"
|
name = "convert_case"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -136,6 +149,12 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encode_unicode"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encoding_rs"
|
name = "encoding_rs"
|
||||||
version = "0.8.32"
|
version = "0.8.32"
|
||||||
|
@ -450,6 +469,12 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.139"
|
version = "0.2.139"
|
||||||
|
@ -518,7 +543,9 @@ name = "lune"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"console",
|
||||||
"hyper",
|
"hyper",
|
||||||
|
"lazy_static",
|
||||||
"mlua",
|
"mlua",
|
||||||
"os_str_bytes",
|
"os_str_bytes",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
@ -1134,6 +1161,12 @@ dependencies = [
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "untrusted"
|
name = "untrusted"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
|
|
|
@ -35,10 +35,10 @@ More examples of how to write Lune scripts can be found in the [examples](.lune/
|
||||||
<details>
|
<details>
|
||||||
<summary><b>🔎 List of APIs</b></summary>
|
<summary><b>🔎 List of APIs</b></summary>
|
||||||
|
|
||||||
`console` - Logging & formatting <br />
|
|
||||||
`fs` - Filesystem <br />
|
`fs` - Filesystem <br />
|
||||||
`net` - Networking <br />
|
`net` - Networking <br />
|
||||||
`process` - Current process & child processes <br />
|
`process` - Current process & child processes <br />
|
||||||
|
`stdio` - Standard input / output & utility functions <br />
|
||||||
`task` - Task scheduler & thread spawning <br />
|
`task` - Task scheduler & thread spawning <br />
|
||||||
|
|
||||||
Documentation for individual members and types can be found using your editor of choice and [Luau LSP](https://github.com/JohnnyMorganz/luau-lsp).
|
Documentation for individual members and types can be found using your editor of choice and [Luau LSP](https://github.com/JohnnyMorganz/luau-lsp).
|
||||||
|
|
32
lune.yml
32
lune.yml
|
@ -1,19 +1,6 @@
|
||||||
# Lune v0.2.2
|
# Lune v0.2.2
|
||||||
---
|
---
|
||||||
globals:
|
globals:
|
||||||
# Console
|
|
||||||
console.resetStyle:
|
|
||||||
args: []
|
|
||||||
console.setStyle:
|
|
||||||
args:
|
|
||||||
- required: false
|
|
||||||
type: string
|
|
||||||
- required: false
|
|
||||||
type: string
|
|
||||||
console.format:
|
|
||||||
must_use: true
|
|
||||||
args:
|
|
||||||
- type: "..."
|
|
||||||
# FS (filesystem)
|
# FS (filesystem)
|
||||||
fs.readFile:
|
fs.readFile:
|
||||||
must_use: true
|
must_use: true
|
||||||
|
@ -80,6 +67,25 @@ globals:
|
||||||
type: table
|
type: table
|
||||||
- required: false
|
- required: false
|
||||||
type: table
|
type: table
|
||||||
|
# Stdio
|
||||||
|
stdio.color:
|
||||||
|
must_use: true
|
||||||
|
args:
|
||||||
|
- type: string
|
||||||
|
stdio.style:
|
||||||
|
must_use: true
|
||||||
|
args:
|
||||||
|
- type: string
|
||||||
|
console.format:
|
||||||
|
must_use: true
|
||||||
|
args:
|
||||||
|
- type: "..."
|
||||||
|
stdio.write:
|
||||||
|
args:
|
||||||
|
- type: string
|
||||||
|
stdio.ewrite:
|
||||||
|
args:
|
||||||
|
- type: string
|
||||||
# Task
|
# Task
|
||||||
task.cancel:
|
task.cancel:
|
||||||
args:
|
args:
|
||||||
|
|
145
luneDocs.json
145
luneDocs.json
|
@ -1,61 +1,4 @@
|
||||||
{
|
{
|
||||||
"@roblox/global/console": {
|
|
||||||
"code_sample": "",
|
|
||||||
"documentation": "Logging & formatting",
|
|
||||||
"keys": {
|
|
||||||
"console": "@roblox/global/console.console"
|
|
||||||
},
|
|
||||||
"learn_more_link": ""
|
|
||||||
},
|
|
||||||
"@roblox/global/console.format": {
|
|
||||||
"code_sample": "",
|
|
||||||
"documentation": "Formats arguments into a human-readable string with syntax highlighting for tables.",
|
|
||||||
"learn_more_link": "",
|
|
||||||
"params": [
|
|
||||||
{
|
|
||||||
"documentation": "@roblox/global/console.format/param/0",
|
|
||||||
"name": "..."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"returns": [
|
|
||||||
"@roblox/global/console.format/return/0"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"@roblox/global/console.format/param/0": {
|
|
||||||
"documentation": "The values to format"
|
|
||||||
},
|
|
||||||
"@roblox/global/console.format/return/0": {
|
|
||||||
"documentation": "The formatted string"
|
|
||||||
},
|
|
||||||
"@roblox/global/console.resetStyle": {
|
|
||||||
"code_sample": "",
|
|
||||||
"documentation": "Resets the current persistent output color and style.",
|
|
||||||
"learn_more_link": "",
|
|
||||||
"params": [],
|
|
||||||
"returns": []
|
|
||||||
},
|
|
||||||
"@roblox/global/console.setStyle": {
|
|
||||||
"code_sample": "",
|
|
||||||
"documentation": "Sets the current persistent output color and / or style.",
|
|
||||||
"learn_more_link": "",
|
|
||||||
"params": [
|
|
||||||
{
|
|
||||||
"documentation": "@roblox/global/console.setStyle/param/0",
|
|
||||||
"name": "color"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"documentation": "@roblox/global/console.setStyle/param/1",
|
|
||||||
"name": "style"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"returns": []
|
|
||||||
},
|
|
||||||
"@roblox/global/console.setStyle/param/0": {
|
|
||||||
"documentation": "The color to set"
|
|
||||||
},
|
|
||||||
"@roblox/global/console.setStyle/param/1": {
|
|
||||||
"documentation": "The style to set"
|
|
||||||
},
|
|
||||||
"@roblox/global/fs": {
|
"@roblox/global/fs": {
|
||||||
"code_sample": "",
|
"code_sample": "",
|
||||||
"documentation": "Filesystem",
|
"documentation": "Filesystem",
|
||||||
|
@ -386,6 +329,94 @@
|
||||||
"@roblox/global/process.spawn/return/0": {
|
"@roblox/global/process.spawn/return/0": {
|
||||||
"documentation": "A dictionary representing the result of the child process"
|
"documentation": "A dictionary representing the result of the child process"
|
||||||
},
|
},
|
||||||
|
"@roblox/global/stdio": {
|
||||||
|
"code_sample": "",
|
||||||
|
"documentation": "Standard input / output & utility functions",
|
||||||
|
"keys": {
|
||||||
|
"stdio": "@roblox/global/stdio.stdio"
|
||||||
|
},
|
||||||
|
"learn_more_link": ""
|
||||||
|
},
|
||||||
|
"@roblox/global/stdio.color": {
|
||||||
|
"code_sample": "",
|
||||||
|
"documentation": "Return an ANSI string that can be used to modify the persistent output color.\n\nPass `\"reset\"` to get a string that can reset the persistent output color.\n\n### Example usage\n\n```lua\nstdio.write(stdio.color(\"red\"))\nprint(\"This text will be red\")\nstdio.write(stdio.color(\"reset\"))\nprint(\"This text will be normal\")\n```",
|
||||||
|
"learn_more_link": "",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"documentation": "@roblox/global/stdio.color/param/0",
|
||||||
|
"name": "color"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"returns": []
|
||||||
|
},
|
||||||
|
"@roblox/global/stdio.color/param/0": {
|
||||||
|
"documentation": "The color to use"
|
||||||
|
},
|
||||||
|
"@roblox/global/stdio.ewrite": {
|
||||||
|
"code_sample": "",
|
||||||
|
"documentation": "Writes a string directly to stderr, without any newline.",
|
||||||
|
"learn_more_link": "",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"documentation": "@roblox/global/stdio.ewrite/param/0",
|
||||||
|
"name": "s"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"returns": []
|
||||||
|
},
|
||||||
|
"@roblox/global/stdio.ewrite/param/0": {
|
||||||
|
"documentation": "The string to write to stderr"
|
||||||
|
},
|
||||||
|
"@roblox/global/stdio.format": {
|
||||||
|
"code_sample": "",
|
||||||
|
"documentation": "Formats arguments into a human-readable string with syntax highlighting for tables.",
|
||||||
|
"learn_more_link": "",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"documentation": "@roblox/global/stdio.format/param/0",
|
||||||
|
"name": "..."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"returns": [
|
||||||
|
"@roblox/global/stdio.format/return/0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@roblox/global/stdio.format/param/0": {
|
||||||
|
"documentation": "The values to format"
|
||||||
|
},
|
||||||
|
"@roblox/global/stdio.format/return/0": {
|
||||||
|
"documentation": "The formatted string"
|
||||||
|
},
|
||||||
|
"@roblox/global/stdio.style": {
|
||||||
|
"code_sample": "",
|
||||||
|
"documentation": "Return an ANSI string that can be used to modify the persistent output style.\n\nPass `\"reset\"` to get a string that can reset the persistent output style.\n\n### Example usage\n\n```lua\nstdio.write(stdio.style(\"bold\"))\nprint(\"This text will be bold\")\nstdio.write(stdio.style(\"reset\"))\nprint(\"This text will be normal\")\n```",
|
||||||
|
"learn_more_link": "",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"documentation": "@roblox/global/stdio.style/param/0",
|
||||||
|
"name": "style"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"returns": []
|
||||||
|
},
|
||||||
|
"@roblox/global/stdio.style/param/0": {
|
||||||
|
"documentation": "The style to use"
|
||||||
|
},
|
||||||
|
"@roblox/global/stdio.write": {
|
||||||
|
"code_sample": "",
|
||||||
|
"documentation": "Writes a string directly to stdout, without any newline.",
|
||||||
|
"learn_more_link": "",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"documentation": "@roblox/global/stdio.write/param/0",
|
||||||
|
"name": "s"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"returns": []
|
||||||
|
},
|
||||||
|
"@roblox/global/stdio.write/param/0": {
|
||||||
|
"documentation": "The string to write to stdout"
|
||||||
|
},
|
||||||
"@roblox/global/task": {
|
"@roblox/global/task": {
|
||||||
"code_sample": "",
|
"code_sample": "",
|
||||||
"documentation": "Task scheduler & thread spawning",
|
"documentation": "Task scheduler & thread spawning",
|
||||||
|
|
106
luneTypes.d.luau
106
luneTypes.d.luau
|
@ -1,40 +1,5 @@
|
||||||
-- Lune v0.2.2
|
-- Lune v0.2.2
|
||||||
|
|
||||||
type ConsoleColor = "black" | "red" | "green" | "yellow" | "blue" | "purple" | "cyan" | "white"
|
|
||||||
type ConsoleStyle = "bold" | "dim"
|
|
||||||
|
|
||||||
--[=[
|
|
||||||
@class console
|
|
||||||
|
|
||||||
Logging & formatting
|
|
||||||
]=]
|
|
||||||
declare console: {
|
|
||||||
--[=[
|
|
||||||
@within console
|
|
||||||
|
|
||||||
Resets the current persistent output color and style.
|
|
||||||
]=]
|
|
||||||
resetStyle: () -> (),
|
|
||||||
--[=[
|
|
||||||
@within console
|
|
||||||
|
|
||||||
Sets the current persistent output color and / or style.
|
|
||||||
|
|
||||||
@param color The color to set
|
|
||||||
@param style The style to set
|
|
||||||
]=]
|
|
||||||
setStyle: (color: ConsoleColor?, style: ConsoleStyle?) -> (),
|
|
||||||
--[=[
|
|
||||||
@within console
|
|
||||||
|
|
||||||
Formats arguments into a human-readable string with syntax highlighting for tables.
|
|
||||||
|
|
||||||
@param ... The values to format
|
|
||||||
@return The formatted string
|
|
||||||
]=]
|
|
||||||
format: (...any) -> (string),
|
|
||||||
}
|
|
||||||
|
|
||||||
--[=[
|
--[=[
|
||||||
@class fs
|
@class fs
|
||||||
|
|
||||||
|
@ -317,6 +282,77 @@ declare process: {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--[=[
|
||||||
|
@class stdio
|
||||||
|
|
||||||
|
Standard input / output & utility functions
|
||||||
|
]=]
|
||||||
|
declare stdio: {
|
||||||
|
--[=[
|
||||||
|
@within stdio
|
||||||
|
|
||||||
|
Return an ANSI string that can be used to modify the persistent output color.
|
||||||
|
|
||||||
|
Pass `"reset"` to get a string that can reset the persistent output color.
|
||||||
|
|
||||||
|
### Example usage
|
||||||
|
|
||||||
|
```lua
|
||||||
|
stdio.write(stdio.color("red"))
|
||||||
|
print("This text will be red")
|
||||||
|
stdio.write(stdio.color("reset"))
|
||||||
|
print("This text will be normal")
|
||||||
|
```
|
||||||
|
|
||||||
|
@param color The color to use
|
||||||
|
]=]
|
||||||
|
color: (color: "reset" | "black" | "red" | "green" | "yellow" | "blue" | "purple" | "cyan" | "white") -> (),
|
||||||
|
--[=[
|
||||||
|
@within stdio
|
||||||
|
|
||||||
|
Return an ANSI string that can be used to modify the persistent output style.
|
||||||
|
|
||||||
|
Pass `"reset"` to get a string that can reset the persistent output style.
|
||||||
|
|
||||||
|
### Example usage
|
||||||
|
|
||||||
|
```lua
|
||||||
|
stdio.write(stdio.style("bold"))
|
||||||
|
print("This text will be bold")
|
||||||
|
stdio.write(stdio.style("reset"))
|
||||||
|
print("This text will be normal")
|
||||||
|
```
|
||||||
|
|
||||||
|
@param style The style to use
|
||||||
|
]=]
|
||||||
|
style: (style: "reset" | "bold" | "dim") -> (),
|
||||||
|
--[=[
|
||||||
|
@within stdio
|
||||||
|
|
||||||
|
Formats arguments into a human-readable string with syntax highlighting for tables.
|
||||||
|
|
||||||
|
@param ... The values to format
|
||||||
|
@return The formatted string
|
||||||
|
]=]
|
||||||
|
format: (...any) -> (string),
|
||||||
|
--[=[
|
||||||
|
@within stdio
|
||||||
|
|
||||||
|
Writes a string directly to stdout, without any newline.
|
||||||
|
|
||||||
|
@param s The string to write to stdout
|
||||||
|
]=]
|
||||||
|
write: (s: string) -> (),
|
||||||
|
--[=[
|
||||||
|
@within stdio
|
||||||
|
|
||||||
|
Writes a string directly to stderr, without any newline.
|
||||||
|
|
||||||
|
@param s The string to write to stderr
|
||||||
|
]=]
|
||||||
|
ewrite: (s: string) -> (),
|
||||||
|
}
|
||||||
|
|
||||||
--[=[
|
--[=[
|
||||||
@class task
|
@class task
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ serde.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
reqwest.workspace = true
|
reqwest.workspace = true
|
||||||
|
|
||||||
|
console = "0.15.5"
|
||||||
|
lazy_static = "1.4.0"
|
||||||
os_str_bytes = "6.4.1"
|
os_str_bytes = "6.4.1"
|
||||||
|
|
||||||
hyper = { version = "0.14.24", features = ["full"] }
|
hyper = { version = "0.14.24", features = ["full"] }
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
use mlua::prelude::*;
|
|
||||||
|
|
||||||
use crate::utils::{
|
|
||||||
formatting::{pretty_format_multi_value, print_color, print_reset, print_style},
|
|
||||||
table::TableBuilder,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<()> {
|
|
||||||
lua.globals().raw_set(
|
|
||||||
"console",
|
|
||||||
TableBuilder::new(lua)?
|
|
||||||
.with_function("resetStyle", |_, _: ()| print_reset())?
|
|
||||||
.with_function(
|
|
||||||
"setStyle",
|
|
||||||
|_, (color, style): (Option<String>, Option<String>)| {
|
|
||||||
if let Some(color) = color {
|
|
||||||
print_color(color)?;
|
|
||||||
}
|
|
||||||
if let Some(style) = style {
|
|
||||||
print_style(style)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
)?
|
|
||||||
.with_function("format", |_, args: LuaMultiValue| {
|
|
||||||
pretty_format_multi_value(&args)
|
|
||||||
})?
|
|
||||||
.build_readonly()?,
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,24 +1,24 @@
|
||||||
mod console;
|
|
||||||
mod fs;
|
mod fs;
|
||||||
mod net;
|
mod net;
|
||||||
mod process;
|
mod process;
|
||||||
mod require;
|
mod require;
|
||||||
|
mod stdio;
|
||||||
mod task;
|
mod task;
|
||||||
|
|
||||||
// Global tables
|
// Global tables
|
||||||
|
|
||||||
pub use console::create as create_console;
|
|
||||||
pub use fs::create as create_fs;
|
pub use fs::create as create_fs;
|
||||||
pub use net::create as create_net;
|
pub use net::create as create_net;
|
||||||
pub use process::create as create_process;
|
pub use process::create as create_process;
|
||||||
pub use require::create as create_require;
|
pub use require::create as create_require;
|
||||||
|
pub use stdio::create as create_stdio;
|
||||||
pub use task::create as create_task;
|
pub use task::create as create_task;
|
||||||
|
|
||||||
// Individual top-level global values
|
// Individual top-level global values
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use crate::utils::formatting::pretty_format_multi_value;
|
use crate::utils::formatting::{format_label, pretty_format_multi_value};
|
||||||
|
|
||||||
pub fn create_top_level(lua: &Lua) -> LuaResult<()> {
|
pub fn create_top_level(lua: &Lua) -> LuaResult<()> {
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
|
@ -42,28 +42,40 @@ pub fn create_top_level(lua: &Lua) -> LuaResult<()> {
|
||||||
globals.raw_set(
|
globals.raw_set(
|
||||||
"info",
|
"info",
|
||||||
lua.create_function(|lua, args: LuaMultiValue| {
|
lua.create_function(|lua, args: LuaMultiValue| {
|
||||||
let formatted = pretty_format_multi_value(&args)?;
|
|
||||||
let print: LuaFunction = lua.named_registry_value("print")?;
|
let print: LuaFunction = lua.named_registry_value("print")?;
|
||||||
print.call(formatted)?;
|
print.call(format!(
|
||||||
|
"{}\n{}",
|
||||||
|
format_label("info"),
|
||||||
|
pretty_format_multi_value(&args)?
|
||||||
|
))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})?,
|
})?,
|
||||||
)?;
|
)?;
|
||||||
globals.raw_set(
|
globals.raw_set(
|
||||||
"warn",
|
"warn",
|
||||||
lua.create_function(|lua, args: LuaMultiValue| {
|
lua.create_function(|lua, args: LuaMultiValue| {
|
||||||
let formatted = pretty_format_multi_value(&args)?;
|
|
||||||
let print: LuaFunction = lua.named_registry_value("print")?;
|
let print: LuaFunction = lua.named_registry_value("print")?;
|
||||||
print.call(formatted)?;
|
print.call(format!(
|
||||||
|
"{}\n{}",
|
||||||
|
format_label("warn"),
|
||||||
|
pretty_format_multi_value(&args)?
|
||||||
|
))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})?,
|
})?,
|
||||||
)?;
|
)?;
|
||||||
globals.raw_set(
|
globals.raw_set(
|
||||||
"error",
|
"error",
|
||||||
lua.create_function(|lua, (arg, level): (LuaValue, Option<u32>)| {
|
lua.create_function(|lua, (arg, level): (LuaValue, Option<u32>)| {
|
||||||
let multi = arg.to_lua_multi(lua)?;
|
|
||||||
let formatted = pretty_format_multi_value(&multi)?;
|
|
||||||
let error: LuaFunction = lua.named_registry_value("error")?;
|
let error: LuaFunction = lua.named_registry_value("error")?;
|
||||||
error.call((formatted, level))?;
|
let multi = arg.to_lua_multi(lua)?;
|
||||||
|
error.call((
|
||||||
|
format!(
|
||||||
|
"{}\n{}",
|
||||||
|
format_label("error"),
|
||||||
|
pretty_format_multi_value(&multi)?
|
||||||
|
),
|
||||||
|
level,
|
||||||
|
))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})?,
|
})?,
|
||||||
)?;
|
)?;
|
||||||
|
|
35
packages/lib/src/globals/stdio.rs
Normal file
35
packages/lib/src/globals/stdio.rs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
use mlua::prelude::*;
|
||||||
|
|
||||||
|
use crate::utils::{
|
||||||
|
formatting::{
|
||||||
|
format_style, pretty_format_multi_value, style_from_color_str, style_from_style_str,
|
||||||
|
},
|
||||||
|
table::TableBuilder,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn create(lua: &Lua) -> LuaResult<()> {
|
||||||
|
lua.globals().raw_set(
|
||||||
|
"stdio",
|
||||||
|
TableBuilder::new(lua)?
|
||||||
|
.with_function("color", |_, color: String| {
|
||||||
|
let ansi_string = format_style(style_from_color_str(&color)?);
|
||||||
|
Ok(ansi_string)
|
||||||
|
})?
|
||||||
|
.with_function("style", |_, style: String| {
|
||||||
|
let ansi_string = format_style(style_from_style_str(&style)?);
|
||||||
|
Ok(ansi_string)
|
||||||
|
})?
|
||||||
|
.with_function("format", |_, args: LuaMultiValue| {
|
||||||
|
pretty_format_multi_value(&args)
|
||||||
|
})?
|
||||||
|
.with_function("write", |_, s: String| {
|
||||||
|
print!("{s}");
|
||||||
|
Ok(())
|
||||||
|
})?
|
||||||
|
.with_function("ewrite", |_, s: String| {
|
||||||
|
eprint!("{s}");
|
||||||
|
Ok(())
|
||||||
|
})?
|
||||||
|
.build_readonly()?,
|
||||||
|
)
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ pub(crate) mod utils;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
globals::{
|
globals::{
|
||||||
create_console, create_fs, create_net, create_process, create_require, create_task,
|
create_fs, create_net, create_process, create_require, create_stdio, create_task,
|
||||||
create_top_level,
|
create_top_level,
|
||||||
},
|
},
|
||||||
utils::formatting::pretty_format_luau_error,
|
utils::formatting::pretty_format_luau_error,
|
||||||
|
@ -16,11 +16,11 @@ use crate::{
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum LuneGlobal {
|
pub enum LuneGlobal {
|
||||||
Console,
|
|
||||||
Fs,
|
Fs,
|
||||||
Net,
|
Net,
|
||||||
Process,
|
Process,
|
||||||
Require,
|
Require,
|
||||||
|
Stdio,
|
||||||
Task,
|
Task,
|
||||||
TopLevel,
|
TopLevel,
|
||||||
}
|
}
|
||||||
|
@ -28,11 +28,11 @@ pub enum LuneGlobal {
|
||||||
impl LuneGlobal {
|
impl LuneGlobal {
|
||||||
pub fn get_all() -> Vec<Self> {
|
pub fn get_all() -> Vec<Self> {
|
||||||
vec![
|
vec![
|
||||||
Self::Console,
|
|
||||||
Self::Fs,
|
Self::Fs,
|
||||||
Self::Net,
|
Self::Net,
|
||||||
Self::Process,
|
Self::Process,
|
||||||
Self::Require,
|
Self::Require,
|
||||||
|
Self::Stdio,
|
||||||
Self::Task,
|
Self::Task,
|
||||||
Self::TopLevel,
|
Self::TopLevel,
|
||||||
]
|
]
|
||||||
|
@ -85,11 +85,11 @@ impl Lune {
|
||||||
// Add in wanted lune globals
|
// Add in wanted lune globals
|
||||||
for global in &self.globals {
|
for global in &self.globals {
|
||||||
match &global {
|
match &global {
|
||||||
LuneGlobal::Console => create_console(&lua)?,
|
|
||||||
LuneGlobal::Fs => create_fs(&lua)?,
|
LuneGlobal::Fs => create_fs(&lua)?,
|
||||||
LuneGlobal::Net => create_net(&lua)?,
|
LuneGlobal::Net => create_net(&lua)?,
|
||||||
LuneGlobal::Process => create_process(&lua, self.args.clone())?,
|
LuneGlobal::Process => create_process(&lua, self.args.clone())?,
|
||||||
LuneGlobal::Require => create_require(&lua)?,
|
LuneGlobal::Require => create_require(&lua)?,
|
||||||
|
LuneGlobal::Stdio => create_stdio(&lua)?,
|
||||||
LuneGlobal::Task => create_task(&lua)?,
|
LuneGlobal::Task => create_task(&lua)?,
|
||||||
LuneGlobal::TopLevel => create_top_level(&lua)?,
|
LuneGlobal::TopLevel => create_top_level(&lua)?,
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ impl Lune {
|
||||||
LuneMessage::LuaError(e) => {
|
LuneMessage::LuaError(e) => {
|
||||||
eprintln!("{}", pretty_format_luau_error(&e));
|
eprintln!("{}", pretty_format_luau_error(&e));
|
||||||
got_error = true;
|
got_error = true;
|
||||||
task_count += 1;
|
task_count -= 1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// If there are no tasks left running, it is now
|
// If there are no tasks left running, it is now
|
||||||
|
@ -180,6 +180,8 @@ mod tests {
|
||||||
use std::{env::set_current_dir, path::PathBuf, process::ExitCode};
|
use std::{env::set_current_dir, path::PathBuf, process::ExitCode};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use console::set_colors_enabled;
|
||||||
|
use console::set_colors_enabled_stderr;
|
||||||
use tokio::fs::read_to_string;
|
use tokio::fs::read_to_string;
|
||||||
|
|
||||||
use crate::Lune;
|
use crate::Lune;
|
||||||
|
@ -191,6 +193,10 @@ mod tests {
|
||||||
$(
|
$(
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn $name() -> Result<ExitCode> {
|
async fn $name() -> Result<ExitCode> {
|
||||||
|
// Disable styling for stdout and stderr since
|
||||||
|
// some tests rely on output not being styled
|
||||||
|
set_colors_enabled(false);
|
||||||
|
set_colors_enabled_stderr(false);
|
||||||
// NOTE: This path is relative to the lib
|
// NOTE: This path is relative to the lib
|
||||||
// package, not the cwd or workspace root,
|
// package, not the cwd or workspace root,
|
||||||
// so we need to cd to the repo root first
|
// so we need to cd to the repo root first
|
||||||
|
@ -218,8 +224,6 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
run_tests! {
|
run_tests! {
|
||||||
console_format: "console/format",
|
|
||||||
console_set_style: "console/set_style",
|
|
||||||
fs_files: "fs/files",
|
fs_files: "fs/files",
|
||||||
fs_dirs: "fs/dirs",
|
fs_dirs: "fs/dirs",
|
||||||
net_request_codes: "net/request/codes",
|
net_request_codes: "net/request/codes",
|
||||||
|
@ -238,6 +242,11 @@ mod tests {
|
||||||
require_nested: "require/tests/nested",
|
require_nested: "require/tests/nested",
|
||||||
require_parents: "require/tests/parents",
|
require_parents: "require/tests/parents",
|
||||||
require_siblings: "require/tests/siblings",
|
require_siblings: "require/tests/siblings",
|
||||||
|
stdio_format: "stdio/format",
|
||||||
|
stdio_color: "stdio/color",
|
||||||
|
stdio_style: "stdio/style",
|
||||||
|
stdio_write: "stdio/write",
|
||||||
|
stdio_ewrite: "stdio/ewrite",
|
||||||
task_cancel: "task/cancel",
|
task_cancel: "task/cancel",
|
||||||
task_defer: "task/defer",
|
task_defer: "task/defer",
|
||||||
task_delay: "task/delay",
|
task_delay: "task/delay",
|
||||||
|
|
|
@ -1,32 +1,28 @@
|
||||||
use std::{
|
use std::fmt::Write;
|
||||||
fmt::Write as _,
|
|
||||||
io::{self, Write as _},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
use console::{style, Style};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
const MAX_FORMAT_DEPTH: usize = 4;
|
const MAX_FORMAT_DEPTH: usize = 4;
|
||||||
|
|
||||||
const INDENT: &str = " ";
|
const INDENT: &str = " ";
|
||||||
|
|
||||||
// TODO: Use some crate for this instead
|
pub const STYLE_RESET_STR: &str = "\x1b[0m";
|
||||||
|
|
||||||
pub const COLOR_RESET: &str = if cfg!(test) { "" } else { "\x1B[0m" };
|
lazy_static! {
|
||||||
pub const COLOR_BLACK: &str = if cfg!(test) { "" } else { "\x1B[30m" };
|
// Colors
|
||||||
pub const COLOR_RED: &str = if cfg!(test) { "" } else { "\x1B[31m" };
|
pub static ref COLOR_BLACK: Style = Style::new().black();
|
||||||
pub const COLOR_GREEN: &str = if cfg!(test) { "" } else { "\x1B[32m" };
|
pub static ref COLOR_RED: Style = Style::new().red();
|
||||||
pub const COLOR_YELLOW: &str = if cfg!(test) { "" } else { "\x1B[33m" };
|
pub static ref COLOR_GREEN: Style = Style::new().green();
|
||||||
pub const COLOR_BLUE: &str = if cfg!(test) { "" } else { "\x1B[34m" };
|
pub static ref COLOR_YELLOW: Style = Style::new().yellow();
|
||||||
pub const COLOR_PURPLE: &str = if cfg!(test) { "" } else { "\x1B[35m" };
|
pub static ref COLOR_BLUE: Style = Style::new().blue();
|
||||||
pub const COLOR_CYAN: &str = if cfg!(test) { "" } else { "\x1B[36m" };
|
pub static ref COLOR_PURPLE: Style = Style::new().magenta();
|
||||||
pub const COLOR_WHITE: &str = if cfg!(test) { "" } else { "\x1B[37m" };
|
pub static ref COLOR_CYAN: Style = Style::new().cyan();
|
||||||
|
pub static ref COLOR_WHITE: Style = Style::new().white();
|
||||||
pub const STYLE_RESET: &str = if cfg!(test) { "" } else { "\x1B[22m" };
|
// Styles
|
||||||
pub const STYLE_BOLD: &str = if cfg!(test) { "" } else { "\x1B[1m" };
|
pub static ref STYLE_BOLD: Style = Style::new().bold();
|
||||||
pub const STYLE_DIM: &str = if cfg!(test) { "" } else { "\x1B[2m" };
|
pub static ref STYLE_DIM: Style = Style::new().dim();
|
||||||
|
|
||||||
pub fn flush_stdout() -> LuaResult<()> {
|
|
||||||
io::stdout().flush().map_err(LuaError::external)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn can_be_plain_lua_table_key(s: &LuaString) -> bool {
|
fn can_be_plain_lua_table_key(s: &LuaString) -> bool {
|
||||||
|
@ -41,74 +37,68 @@ fn can_be_plain_lua_table_key(s: &LuaString) -> bool {
|
||||||
|
|
||||||
pub fn format_label<S: AsRef<str>>(s: S) -> String {
|
pub fn format_label<S: AsRef<str>>(s: S) -> String {
|
||||||
format!(
|
format!(
|
||||||
"{}[{}{}{}{}]{} ",
|
"{}{}{} ",
|
||||||
STYLE_BOLD,
|
style("[").bold(),
|
||||||
match s.as_ref().to_ascii_lowercase().as_str() {
|
match s.as_ref().to_ascii_lowercase().as_str() {
|
||||||
"info" => COLOR_BLUE,
|
"info" => style("INFO").blue(),
|
||||||
"warn" => COLOR_YELLOW,
|
"warn" => style("WARN").yellow(),
|
||||||
"error" => COLOR_RED,
|
"error" => style("ERROR").red(),
|
||||||
_ => COLOR_WHITE,
|
_ => style(""),
|
||||||
},
|
},
|
||||||
s.as_ref().to_ascii_uppercase(),
|
style("]").bold()
|
||||||
COLOR_RESET,
|
|
||||||
STYLE_BOLD,
|
|
||||||
STYLE_RESET
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_label<S: AsRef<str>>(s: S) -> LuaResult<()> {
|
pub fn format_style(style: Option<&'static Style>) -> String {
|
||||||
print!("{}", format_label(s));
|
if cfg!(test) {
|
||||||
flush_stdout()?;
|
"".to_string()
|
||||||
Ok(())
|
} else if let Some(style) = style {
|
||||||
|
// HACK: We have no direct way of referencing the ansi color code
|
||||||
|
// of the style that console::Style provides, and we also know for
|
||||||
|
// sure that styles always include the reset sequence at the end
|
||||||
|
style
|
||||||
|
.apply_to("")
|
||||||
|
.to_string()
|
||||||
|
.strip_suffix(STYLE_RESET_STR)
|
||||||
|
.unwrap()
|
||||||
|
.to_string()
|
||||||
|
} else {
|
||||||
|
STYLE_RESET_STR.to_string()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_style<S: AsRef<str>>(s: S) -> LuaResult<()> {
|
pub fn style_from_color_str<S: AsRef<str>>(s: S) -> LuaResult<Option<&'static Style>> {
|
||||||
print!(
|
Ok(match s.as_ref() {
|
||||||
"{}",
|
"reset" => None,
|
||||||
match s.as_ref() {
|
"black" => Some(&COLOR_BLACK),
|
||||||
"reset" => STYLE_RESET,
|
"red" => Some(&COLOR_RED),
|
||||||
"bold" => STYLE_BOLD,
|
"green" => Some(&COLOR_GREEN),
|
||||||
"dim" => STYLE_DIM,
|
"yellow" => Some(&COLOR_YELLOW),
|
||||||
_ => {
|
"blue" => Some(&COLOR_BLUE),
|
||||||
return Err(LuaError::RuntimeError(format!(
|
"purple" => Some(&COLOR_PURPLE),
|
||||||
"The style '{}' is not a valid style name",
|
"cyan" => Some(&COLOR_CYAN),
|
||||||
s.as_ref()
|
"white" => Some(&COLOR_WHITE),
|
||||||
)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
flush_stdout()?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn print_reset() -> LuaResult<()> {
|
|
||||||
print_style("reset")?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn print_color<S: AsRef<str>>(s: S) -> LuaResult<()> {
|
|
||||||
print!(
|
|
||||||
"{}",
|
|
||||||
match s.as_ref() {
|
|
||||||
"reset" => COLOR_RESET,
|
|
||||||
"black" => COLOR_BLACK,
|
|
||||||
"red" => COLOR_RED,
|
|
||||||
"green" => COLOR_GREEN,
|
|
||||||
"yellow" => COLOR_YELLOW,
|
|
||||||
"blue" => COLOR_BLUE,
|
|
||||||
"purple" => COLOR_PURPLE,
|
|
||||||
"cyan" => COLOR_CYAN,
|
|
||||||
"white" => COLOR_WHITE,
|
|
||||||
_ => {
|
_ => {
|
||||||
return Err(LuaError::RuntimeError(format!(
|
return Err(LuaError::RuntimeError(format!(
|
||||||
"The color '{}' is not a valid color name",
|
"The color '{}' is not a valid color name",
|
||||||
s.as_ref()
|
s.as_ref()
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
);
|
|
||||||
flush_stdout()?;
|
pub fn style_from_style_str<S: AsRef<str>>(s: S) -> LuaResult<Option<&'static Style>> {
|
||||||
Ok(())
|
Ok(match s.as_ref() {
|
||||||
|
"reset" => None,
|
||||||
|
"bold" => Some(&STYLE_BOLD),
|
||||||
|
"dim" => Some(&STYLE_DIM),
|
||||||
|
_ => {
|
||||||
|
return Err(LuaError::RuntimeError(format!(
|
||||||
|
"The style '{}' is not a valid style name",
|
||||||
|
s.as_ref()
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pretty_format_value(
|
pub fn pretty_format_value(
|
||||||
|
@ -119,65 +109,66 @@ pub fn pretty_format_value(
|
||||||
// TODO: Handle tables with cyclic references
|
// TODO: Handle tables with cyclic references
|
||||||
match &value {
|
match &value {
|
||||||
LuaValue::Nil => write!(buffer, "nil")?,
|
LuaValue::Nil => write!(buffer, "nil")?,
|
||||||
LuaValue::Boolean(true) => write!(buffer, "{COLOR_YELLOW}true{COLOR_RESET}")?,
|
LuaValue::Boolean(true) => write!(buffer, "{}", COLOR_YELLOW.apply_to("true"))?,
|
||||||
LuaValue::Boolean(false) => write!(buffer, "{COLOR_YELLOW}false{COLOR_RESET}")?,
|
LuaValue::Boolean(false) => write!(buffer, "{}", COLOR_YELLOW.apply_to("false"))?,
|
||||||
LuaValue::Number(n) => write!(buffer, "{COLOR_CYAN}{n}{COLOR_RESET}")?,
|
LuaValue::Number(n) => write!(buffer, "{}", COLOR_CYAN.apply_to(format!("{n}")))?,
|
||||||
LuaValue::Integer(i) => write!(buffer, "{COLOR_CYAN}{i}{COLOR_RESET}")?,
|
LuaValue::Integer(i) => write!(buffer, "{}", COLOR_CYAN.apply_to(format!("{i}")))?,
|
||||||
LuaValue::String(s) => write!(
|
LuaValue::String(s) => write!(
|
||||||
buffer,
|
buffer,
|
||||||
"{}\"{}\"{}",
|
"\"{}\"",
|
||||||
COLOR_GREEN,
|
COLOR_GREEN.apply_to(
|
||||||
s.to_string_lossy()
|
s.to_string_lossy()
|
||||||
.replace('"', r#"\""#)
|
.replace('"', r#"\""#)
|
||||||
.replace('\r', r#"\r"#)
|
.replace('\r', r#"\r"#)
|
||||||
.replace('\n', r#"\n"#),
|
.replace('\n', r#"\n"#)
|
||||||
COLOR_RESET
|
)
|
||||||
)?,
|
)?,
|
||||||
LuaValue::Table(ref tab) => {
|
LuaValue::Table(ref tab) => {
|
||||||
if depth >= MAX_FORMAT_DEPTH {
|
if depth >= MAX_FORMAT_DEPTH {
|
||||||
write!(buffer, "{STYLE_DIM}{{ ... }}{STYLE_RESET}")?;
|
write!(buffer, "{}", STYLE_DIM.apply_to("{ ... }"))?;
|
||||||
} else {
|
} else {
|
||||||
let mut is_empty = false;
|
let mut is_empty = false;
|
||||||
let depth_indent = INDENT.repeat(depth);
|
let depth_indent = INDENT.repeat(depth);
|
||||||
write!(buffer, "{STYLE_DIM}{{{STYLE_RESET}")?;
|
write!(buffer, "{}", STYLE_DIM.apply_to("{"))?;
|
||||||
for pair in tab.clone().pairs::<LuaValue, LuaValue>() {
|
for pair in tab.clone().pairs::<LuaValue, LuaValue>() {
|
||||||
let (key, value) = pair.unwrap();
|
let (key, value) = pair.unwrap();
|
||||||
match &key {
|
match &key {
|
||||||
LuaValue::String(s) if can_be_plain_lua_table_key(s) => write!(
|
LuaValue::String(s) if can_be_plain_lua_table_key(s) => write!(
|
||||||
buffer,
|
buffer,
|
||||||
"\n{}{}{} {}={} ",
|
"\n{}{}{} {} ",
|
||||||
depth_indent,
|
depth_indent,
|
||||||
INDENT,
|
INDENT,
|
||||||
s.to_string_lossy(),
|
s.to_string_lossy(),
|
||||||
STYLE_DIM,
|
STYLE_DIM.apply_to("=")
|
||||||
STYLE_RESET
|
|
||||||
)?,
|
)?,
|
||||||
_ => {
|
_ => {
|
||||||
write!(buffer, "\n{depth_indent}{INDENT}[")?;
|
write!(buffer, "\n{depth_indent}{INDENT}[")?;
|
||||||
pretty_format_value(buffer, &key, depth)?;
|
pretty_format_value(buffer, &key, depth)?;
|
||||||
write!(buffer, "] {STYLE_DIM}={STYLE_RESET} ")?;
|
write!(buffer, "] {} ", STYLE_DIM.apply_to("="))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pretty_format_value(buffer, &value, depth + 1)?;
|
pretty_format_value(buffer, &value, depth + 1)?;
|
||||||
write!(buffer, "{STYLE_DIM},{STYLE_RESET}")?;
|
write!(buffer, "{}", STYLE_DIM.apply_to(","))?;
|
||||||
is_empty = false;
|
is_empty = false;
|
||||||
}
|
}
|
||||||
if is_empty {
|
if is_empty {
|
||||||
write!(buffer, " {STYLE_DIM}}}{STYLE_RESET}")?;
|
write!(buffer, "{}", STYLE_DIM.apply_to(" }"))?;
|
||||||
} else {
|
} else {
|
||||||
write!(buffer, "\n{depth_indent}{STYLE_DIM}}}{STYLE_RESET}")?;
|
write!(buffer, "\n{}", STYLE_DIM.apply_to("}"))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LuaValue::Vector(x, y, z) => {
|
LuaValue::Vector(x, y, z) => write!(
|
||||||
write!(buffer, "{COLOR_PURPLE}<vector({x}, {y}, {z})>{COLOR_RESET}",)?
|
buffer,
|
||||||
}
|
"{}",
|
||||||
LuaValue::Thread(_) => write!(buffer, "{COLOR_PURPLE}<thread>{COLOR_RESET}")?,
|
COLOR_PURPLE.apply_to(format!("<vector({x}, {y}, {z})>"))
|
||||||
LuaValue::Function(_) => write!(buffer, "{COLOR_PURPLE}<function>{COLOR_RESET}")?,
|
)?,
|
||||||
|
LuaValue::Thread(_) => write!(buffer, "{}", COLOR_PURPLE.apply_to("<thread>"))?,
|
||||||
|
LuaValue::Function(_) => write!(buffer, "{}", COLOR_PURPLE.apply_to("<function>"))?,
|
||||||
LuaValue::UserData(_) | LuaValue::LightUserData(_) => {
|
LuaValue::UserData(_) | LuaValue::LightUserData(_) => {
|
||||||
write!(buffer, "{COLOR_PURPLE}<userdata>{COLOR_RESET}")?
|
write!(buffer, "{}", COLOR_PURPLE.apply_to("<userdata>"))?
|
||||||
}
|
}
|
||||||
_ => write!(buffer, "?")?,
|
_ => write!(buffer, "{}", STYLE_DIM.apply_to("?"))?,
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -200,8 +191,8 @@ pub fn pretty_format_multi_value(multi: &LuaMultiValue) -> LuaResult<String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pretty_format_luau_error(e: &LuaError) -> String {
|
pub fn pretty_format_luau_error(e: &LuaError) -> String {
|
||||||
let stack_begin = format!("[{}Stack Begin{}]", COLOR_BLUE, COLOR_RESET);
|
let stack_begin = format!("[{}]", COLOR_BLUE.apply_to("Stack Begin"));
|
||||||
let stack_end = format!("[{}Stack End{}]", COLOR_BLUE, COLOR_RESET);
|
let stack_end = format!("[{}]", COLOR_BLUE.apply_to("Stack End"));
|
||||||
let err_string = match e {
|
let err_string = match e {
|
||||||
LuaError::RuntimeError(e) => {
|
LuaError::RuntimeError(e) => {
|
||||||
// Remove unnecessary prefix
|
// Remove unnecessary prefix
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
local STYLES_VALID = { "bold", "dim" }
|
|
||||||
local STYLES_INVALID = { "", "*bold*", "dimm", "megabright", "cheerful", "sad", " " }
|
|
||||||
|
|
||||||
local COLORS_VALID = { "black", "red", "green", "yellow", "blue", "purple", "cyan", "white" }
|
|
||||||
local COLORS_INVALID = { "", "gray", "grass", "red?", "super red", " ", "none" }
|
|
||||||
|
|
||||||
-- Test colors
|
|
||||||
|
|
||||||
for _, color in COLORS_VALID do
|
|
||||||
if not pcall(console.setStyle, color :: any, nil) then
|
|
||||||
error(string.format("Setting color failed for color '%s'", color))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, color in COLORS_INVALID do
|
|
||||||
if pcall(console.setStyle, color :: any, nil) then
|
|
||||||
console.resetStyle()
|
|
||||||
error(string.format("Setting color should have failed for color '%s' but succeeded", color))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Test styles
|
|
||||||
|
|
||||||
for _, style in STYLES_VALID do
|
|
||||||
if not pcall(console.setStyle, nil, style :: any) then
|
|
||||||
error(string.format("Setting style failed for style '%s'", style))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, style in STYLES_INVALID do
|
|
||||||
if pcall(console.setStyle, nil, style :: any) then
|
|
||||||
console.resetStyle()
|
|
||||||
error(string.format("Setting style should have failed for style '%s' but succeeded", style))
|
|
||||||
end
|
|
||||||
end
|
|
15
tests/stdio/color.luau
Normal file
15
tests/stdio/color.luau
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
local COLORS_VALID =
|
||||||
|
{ "reset", "black", "red", "green", "yellow", "blue", "purple", "cyan", "white" }
|
||||||
|
local COLORS_INVALID = { "", "gray", "grass", "red?", "super red", " ", "none" }
|
||||||
|
|
||||||
|
for _, color in COLORS_VALID do
|
||||||
|
stdio.color(color :: any)
|
||||||
|
stdio.color("reset")
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, color in COLORS_INVALID do
|
||||||
|
if pcall(stdio.color, color :: any) then
|
||||||
|
stdio.color("reset")
|
||||||
|
error(string.format("Setting color should have failed for color '%s' but succeeded", color))
|
||||||
|
end
|
||||||
|
end
|
3
tests/stdio/ewrite.luau
Normal file
3
tests/stdio/ewrite.luau
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
stdio.ewrite("Hello, stderr!")
|
||||||
|
|
||||||
|
process.exit(0)
|
|
@ -1,10 +1,10 @@
|
||||||
assert(
|
assert(
|
||||||
console.format("Hello", "world", "!") == "Hello world !",
|
stdio.format("Hello", "world", "!") == "Hello world !",
|
||||||
"Format should add a single space between arguments"
|
"Format should add a single space between arguments"
|
||||||
)
|
)
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
console.format({ Hello = "World" }) == '{\n Hello = "World",\n}',
|
stdio.format({ Hello = "World" }) == '{\n Hello = "World",\n}',
|
||||||
"Format should print out proper tables"
|
"Format should print out proper tables"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,6 +21,6 @@ local nested = {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
string.find(console.format(nested), "Nesting = { ... }", 1, true) ~= nil,
|
string.find(stdio.format(nested), "Nesting = { ... }", 1, true) ~= nil,
|
||||||
"Format should print 4 levels of nested tables before cutting off"
|
"Format should print 4 levels of nested tables before cutting off"
|
||||||
)
|
)
|
14
tests/stdio/style.luau
Normal file
14
tests/stdio/style.luau
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
local STYLES_VALID = { "reset", "bold", "dim" }
|
||||||
|
local STYLES_INVALID = { "", "*bold*", "dimm", "megabright", "cheerful", "sad", " " }
|
||||||
|
|
||||||
|
for _, style in STYLES_VALID do
|
||||||
|
stdio.style(style :: any)
|
||||||
|
stdio.style("reset")
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, style in STYLES_INVALID do
|
||||||
|
if pcall(stdio.style, style :: any) then
|
||||||
|
stdio.style("reset")
|
||||||
|
error(string.format("Setting style should have failed for style '%s' but succeeded", style))
|
||||||
|
end
|
||||||
|
end
|
3
tests/stdio/write.luau
Normal file
3
tests/stdio/write.luau
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
stdio.write("Hello, stdout!")
|
||||||
|
|
||||||
|
process.exit(0)
|
|
@ -5,7 +5,7 @@ return function(index: number, type: string, value: any)
|
||||||
"Expected argument #%d to be of type %s, got %s",
|
"Expected argument #%d to be of type %s, got %s",
|
||||||
index,
|
index,
|
||||||
type,
|
type,
|
||||||
console.format(value)
|
stdio.format(value)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue