Showing preview only (1,204K chars total). Download the full file or copy to clipboard to get everything.
Repository: filiptibell/lune
Branch: main
Commit: 43484f131c3e
Files: 457
Total size: 1.1 MB
Directory structure:
gitextract_9kvtan03/
├── .cargo/
│ └── config.toml
├── .editorconfig
├── .gitattributes
├── .github/
│ └── workflows/
│ ├── ci.yaml
│ └── release.yaml
├── .gitignore
├── .gitmodules
├── .luaurc
├── .lune/
│ ├── csv_printer.luau
│ ├── data/
│ │ └── test.csv
│ ├── hello_lune.luau
│ ├── http_server.luau
│ ├── websocket_client.luau
│ └── websocket_server.luau
├── .vscode/
│ ├── extensions.json
│ └── settings.json
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Cargo.toml
├── LICENSE.txt
├── README.md
├── crates/
│ ├── lune/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── cli/
│ │ │ ├── build/
│ │ │ │ ├── base_exe.rs
│ │ │ │ ├── files.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── result.rs
│ │ │ │ └── target.rs
│ │ │ ├── list.rs
│ │ │ ├── mod.rs
│ │ │ ├── repl.rs
│ │ │ ├── run.rs
│ │ │ ├── setup.rs
│ │ │ └── utils/
│ │ │ ├── files.rs
│ │ │ ├── listing.rs
│ │ │ └── mod.rs
│ │ ├── lib.rs
│ │ ├── main.rs
│ │ ├── rt/
│ │ │ ├── mod.rs
│ │ │ ├── result.rs
│ │ │ └── runtime.rs
│ │ ├── standalone/
│ │ │ ├── metadata.rs
│ │ │ ├── mod.rs
│ │ │ └── tracer.rs
│ │ └── tests.rs
│ ├── lune-roblox/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── datatypes/
│ │ │ ├── attributes.rs
│ │ │ ├── conversion.rs
│ │ │ ├── extension.rs
│ │ │ ├── mod.rs
│ │ │ ├── result.rs
│ │ │ ├── types/
│ │ │ │ ├── axes.rs
│ │ │ │ ├── brick_color.rs
│ │ │ │ ├── cframe.rs
│ │ │ │ ├── color3.rs
│ │ │ │ ├── color_sequence.rs
│ │ │ │ ├── color_sequence_keypoint.rs
│ │ │ │ ├── content.rs
│ │ │ │ ├── enum.rs
│ │ │ │ ├── enum_item.rs
│ │ │ │ ├── enums.rs
│ │ │ │ ├── faces.rs
│ │ │ │ ├── font.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── number_range.rs
│ │ │ │ ├── number_sequence.rs
│ │ │ │ ├── number_sequence_keypoint.rs
│ │ │ │ ├── physical_properties.rs
│ │ │ │ ├── ray.rs
│ │ │ │ ├── rect.rs
│ │ │ │ ├── region3.rs
│ │ │ │ ├── region3int16.rs
│ │ │ │ ├── udim.rs
│ │ │ │ ├── udim2.rs
│ │ │ │ ├── unique_id.rs
│ │ │ │ ├── vector2.rs
│ │ │ │ ├── vector2int16.rs
│ │ │ │ ├── vector3.rs
│ │ │ │ └── vector3int16.rs
│ │ │ └── util.rs
│ │ ├── document/
│ │ │ ├── error.rs
│ │ │ ├── format.rs
│ │ │ ├── kind.rs
│ │ │ ├── mod.rs
│ │ │ └── postprocessing.rs
│ │ ├── exports.rs
│ │ ├── instance/
│ │ │ ├── base.rs
│ │ │ ├── data_model.rs
│ │ │ ├── mod.rs
│ │ │ ├── registry.rs
│ │ │ ├── terrain.rs
│ │ │ └── workspace.rs
│ │ ├── lib.rs
│ │ ├── reflection/
│ │ │ ├── class.rs
│ │ │ ├── enums.rs
│ │ │ ├── mod.rs
│ │ │ ├── property.rs
│ │ │ └── utils.rs
│ │ └── shared/
│ │ ├── classes.rs
│ │ ├── instance.rs
│ │ ├── mod.rs
│ │ └── userdata.rs
│ ├── lune-std/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── global.rs
│ │ ├── globals/
│ │ │ ├── g_table.rs
│ │ │ ├── mod.rs
│ │ │ ├── print.rs
│ │ │ ├── require.rs
│ │ │ ├── version.rs
│ │ │ └── warn.rs
│ │ ├── lib.rs
│ │ ├── library.rs
│ │ └── require/
│ │ ├── loader.rs
│ │ ├── mod.rs
│ │ └── resolver.rs
│ ├── lune-std-datetime/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── date_time.rs
│ │ │ ├── lib.rs
│ │ │ ├── result.rs
│ │ │ └── values.rs
│ │ └── types.d.luau
│ ├── lune-std-fs/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── copy.rs
│ │ │ ├── lib.rs
│ │ │ ├── metadata.rs
│ │ │ └── options.rs
│ │ └── types.d.luau
│ ├── lune-std-luau/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── lib.rs
│ │ │ └── options.rs
│ │ └── types.d.luau
│ ├── lune-std-net/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── body/
│ │ │ │ ├── cursor.rs
│ │ │ │ ├── incoming.rs
│ │ │ │ ├── inner.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── readable.rs
│ │ │ ├── client/
│ │ │ │ ├── fetch.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── rustls.rs
│ │ │ │ ├── send.rs
│ │ │ │ ├── stream.rs
│ │ │ │ └── tcp.rs
│ │ │ ├── lib.rs
│ │ │ ├── server/
│ │ │ │ ├── config.rs
│ │ │ │ ├── handle.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── service.rs
│ │ │ │ └── upgrade.rs
│ │ │ ├── shared/
│ │ │ │ ├── futures.rs
│ │ │ │ ├── headers.rs
│ │ │ │ ├── hyper.rs
│ │ │ │ ├── lua.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── request.rs
│ │ │ │ ├── response.rs
│ │ │ │ ├── tcp.rs
│ │ │ │ └── websocket.rs
│ │ │ └── url/
│ │ │ ├── decode.rs
│ │ │ ├── encode.rs
│ │ │ └── mod.rs
│ │ └── types.d.luau
│ ├── lune-std-process/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── create/
│ │ │ │ ├── child.rs
│ │ │ │ ├── child_reader.rs
│ │ │ │ ├── child_writer.rs
│ │ │ │ └── mod.rs
│ │ │ ├── exec/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── tee_writer.rs
│ │ │ │ └── wait_for_child.rs
│ │ │ ├── lib.rs
│ │ │ └── options/
│ │ │ ├── kind.rs
│ │ │ ├── mod.rs
│ │ │ └── stdio.rs
│ │ └── types.d.luau
│ ├── lune-std-regex/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── captures.rs
│ │ │ ├── lib.rs
│ │ │ ├── matches.rs
│ │ │ └── regex.rs
│ │ └── types.d.luau
│ ├── lune-std-roblox/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ └── lib.rs
│ │ └── types.d.luau
│ ├── lune-std-serde/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── compress_decompress.rs
│ │ │ ├── encode_decode.rs
│ │ │ ├── hash.rs
│ │ │ └── lib.rs
│ │ └── types.d.luau
│ ├── lune-std-stdio/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── lib.rs
│ │ │ ├── prompt.rs
│ │ │ └── style_and_color.rs
│ │ └── types.d.luau
│ ├── lune-std-task/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ └── lib.rs
│ │ └── types.d.luau
│ ├── lune-utils/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── fmt/
│ │ │ ├── error/
│ │ │ │ ├── components.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── stack_trace.rs
│ │ │ │ └── tests.rs
│ │ │ ├── label.rs
│ │ │ ├── mod.rs
│ │ │ └── value/
│ │ │ ├── basic.rs
│ │ │ ├── config.rs
│ │ │ ├── metamethods.rs
│ │ │ ├── mod.rs
│ │ │ ├── recursive.rs
│ │ │ └── style.rs
│ │ ├── lib.rs
│ │ ├── path/
│ │ │ ├── constants.rs
│ │ │ ├── luau.rs
│ │ │ ├── mod.rs
│ │ │ └── std.rs
│ │ ├── process/
│ │ │ ├── args.rs
│ │ │ ├── env.rs
│ │ │ ├── jit.rs
│ │ │ └── mod.rs
│ │ ├── table_builder.rs
│ │ └── version_string.rs
│ └── mlua-luau-scheduler/
│ ├── Cargo.toml
│ ├── README.md
│ ├── examples/
│ │ ├── basic_sleep.rs
│ │ ├── basic_spawn.rs
│ │ ├── callbacks.rs
│ │ ├── exit_code.rs
│ │ ├── lots_of_threads.rs
│ │ ├── lua/
│ │ │ ├── basic_sleep.luau
│ │ │ ├── basic_spawn.luau
│ │ │ ├── callbacks.luau
│ │ │ ├── exit_code.luau
│ │ │ ├── lots_of_threads.luau
│ │ │ └── scheduler_ordering.luau
│ │ ├── scheduler_ordering.rs
│ │ └── tracy.rs
│ └── src/
│ ├── error_callback.rs
│ ├── events/
│ │ ├── mod.rs
│ │ ├── multi.rs
│ │ └── once.rs
│ ├── exit.rs
│ ├── functions.rs
│ ├── lib.rs
│ ├── queue/
│ │ ├── deferred.rs
│ │ ├── futures.rs
│ │ ├── mod.rs
│ │ ├── spawned.rs
│ │ └── threads.rs
│ ├── scheduler.rs
│ ├── status.rs
│ ├── threads/
│ │ ├── id.rs
│ │ ├── map.rs
│ │ └── mod.rs
│ ├── traits.rs
│ └── util.rs
├── rokit.toml
├── scripts/
│ ├── analyze.sh
│ ├── analyze_copy_typedefs.luau
│ ├── brick_color.luau
│ ├── font_enum_map.luau
│ ├── format-check.sh
│ ├── format.sh
│ ├── generate_compression_test_files.luau
│ ├── get-version.sh
│ ├── physical_properties_enum_map.luau
│ ├── unpack-releases.sh
│ └── zip-release.sh
├── stylua.toml
└── tests/
├── datetime/
│ ├── formatLocalTime.luau
│ ├── formatUniversalTime.luau
│ ├── fromLocalTime.luau
│ ├── fromRfc2822.luau
│ ├── fromRfc3339.luau
│ ├── fromUniversalTime.luau
│ ├── fromUnixTimestamp.luau
│ ├── now.luau
│ ├── toLocalTime.luau
│ ├── toRfc2822.luau
│ ├── toRfc3339.luau
│ └── toUniversalTime.luau
├── fs/
│ ├── copy.luau
│ ├── dirs.luau
│ ├── files.luau
│ ├── metadata.luau
│ ├── move.luau
│ └── utils.luau
├── globals/
│ ├── _G.luau
│ ├── _VERSION.luau
│ ├── coroutine.luau
│ ├── error.luau
│ ├── pcall.luau
│ ├── type.luau
│ ├── typeof.luau
│ └── warn.luau
├── luau/
│ ├── compile.luau
│ ├── load.luau
│ ├── options.luau
│ └── safeenv.luau
├── net/
│ ├── request/
│ │ ├── codes.luau
│ │ ├── compression.luau
│ │ ├── https.luau
│ │ ├── methods.luau
│ │ ├── query.luau
│ │ ├── redirect.luau
│ │ ├── user_agent.luau
│ │ └── util.luau
│ ├── serve/
│ │ ├── addresses.luau
│ │ ├── handles.luau
│ │ ├── non_blocking.luau
│ │ ├── requests.luau
│ │ └── websockets.luau
│ ├── socket/
│ │ ├── basic.luau
│ │ ├── wss.luau
│ │ └── wss_rw.luau
│ ├── tcp/
│ │ ├── basic.luau
│ │ ├── info.luau
│ │ └── tls.luau
│ └── url/
│ ├── decode.luau
│ └── encode.luau
├── process/
│ ├── args.luau
│ ├── create/
│ │ ├── kill.luau
│ │ ├── non_blocking.luau
│ │ ├── status.luau
│ │ └── stream.luau
│ ├── cwd.luau
│ ├── env.luau
│ ├── exec/
│ │ ├── async.luau
│ │ ├── basic.luau
│ │ ├── cwd.luau
│ │ ├── no_panic.luau
│ │ ├── shell.luau
│ │ ├── stdin.luau
│ │ └── stdio.luau
│ └── exit.luau
├── regex/
│ ├── general.luau
│ ├── metamethods.luau
│ └── replace.luau
├── require/
│ ├── modules/
│ │ ├── init.luau
│ │ └── module.luau
│ └── tests/
│ ├── aliases.luau
│ ├── async.luau
│ ├── async_concurrent.luau
│ ├── async_sequential.luau
│ ├── builtins.luau
│ ├── children.luau
│ ├── init_files.luau
│ ├── invalid.luau
│ ├── module.luau
│ ├── modules/
│ │ ├── async.luau
│ │ ├── init.luau
│ │ ├── module.luau
│ │ ├── modules/
│ │ │ ├── init.luau
│ │ │ └── module.luau
│ │ ├── nested.luau
│ │ └── self_alias/
│ │ ├── init.luau
│ │ └── module.luau
│ ├── multi.ext.file.luau
│ ├── multi_ext.luau
│ ├── nested.luau
│ ├── parents.luau
│ ├── siblings.luau
│ ├── state.luau
│ ├── state_module.luau
│ └── state_second.luau
├── roblox/
│ ├── datatypes/
│ │ ├── Axes.luau
│ │ ├── BrickColor.luau
│ │ ├── CFrame.luau
│ │ ├── Color3.luau
│ │ ├── ColorSequence.luau
│ │ ├── ColorSequenceKeypoint.luau
│ │ ├── Content.luau
│ │ ├── Enum.luau
│ │ ├── Faces.luau
│ │ ├── Font.luau
│ │ ├── NumberRange.luau
│ │ ├── NumberSequence.luau
│ │ ├── NumberSequenceKeypoint.luau
│ │ ├── PhysicalProperties.luau
│ │ ├── Ray.luau
│ │ ├── Rect.luau
│ │ ├── Region3.luau
│ │ ├── Region3int16.luau
│ │ ├── UDim.luau
│ │ ├── UDim2.luau
│ │ ├── UniqueId.luau
│ │ ├── Vector2.luau
│ │ ├── Vector2int16.luau
│ │ ├── Vector3.luau
│ │ └── Vector3int16.luau
│ ├── files/
│ │ ├── deserializeModel.luau
│ │ ├── deserializePlace.luau
│ │ ├── serializeModel.luau
│ │ └── serializePlace.luau
│ ├── instance/
│ │ ├── attributes.luau
│ │ ├── classes/
│ │ │ ├── DataModel.luau
│ │ │ ├── Terrain.luau
│ │ │ └── Workspace.luau
│ │ ├── custom/
│ │ │ ├── async.luau
│ │ │ ├── methods.luau
│ │ │ └── properties.luau
│ │ ├── methods/
│ │ │ ├── ClearAllChildren.luau
│ │ │ ├── Clone.luau
│ │ │ ├── Destroy.luau
│ │ │ ├── FindFirstAncestor.luau
│ │ │ ├── FindFirstAncestorOfClass.luau
│ │ │ ├── FindFirstAncestorWhichIsA.luau
│ │ │ ├── FindFirstChild.luau
│ │ │ ├── FindFirstChildOfClass.luau
│ │ │ ├── FindFirstChildWhichIsA.luau
│ │ │ ├── GetChildren.luau
│ │ │ ├── GetDebugId.luau
│ │ │ ├── GetDescendants.luau
│ │ │ ├── GetFullName.luau
│ │ │ ├── IsA.luau
│ │ │ ├── IsAncestorOf.luau
│ │ │ └── IsDescendantOf.luau
│ │ ├── new.luau
│ │ ├── properties.luau
│ │ └── tags.luau
│ ├── misc/
│ │ └── typeof.luau
│ └── reflection/
│ ├── class.luau
│ ├── database.luau
│ ├── enums.luau
│ └── property.luau
├── serde/
│ ├── compression/
│ │ ├── files.luau
│ │ └── roundtrip.luau
│ ├── hashing/
│ │ ├── hash.luau
│ │ └── hmac.luau
│ ├── json/
│ │ ├── decode.luau
│ │ ├── encode.luau
│ │ └── source.luau
│ ├── jsonc/
│ │ ├── decode.luau
│ │ ├── encode.luau
│ │ └── source.luau
│ ├── test-files/
│ │ ├── loremipsum.txt
│ │ ├── loremipsum.txt.br
│ │ ├── loremipsum.txt.lz4
│ │ ├── loremipsum.txt.z
│ │ ├── loremipsum.txt.zst
│ │ ├── uncompressed.csv
│ │ ├── uncompressed.json
│ │ └── uncompressed.yaml
│ └── toml/
│ ├── decode.luau
│ ├── encode.luau
│ └── source.luau
├── stdio/
│ ├── color.luau
│ ├── ewrite.luau
│ ├── format.luau
│ ├── prompt.luau
│ ├── style.luau
│ └── write.luau
└── task/
├── cancel.luau
├── defer.luau
├── delay.luau
├── fcheck.luau
├── spawn.luau
└── wait.luau
================================================
FILE CONTENTS
================================================
================================================
FILE: .cargo/config.toml
================================================
# Statically link the vcruntime
# https://users.rust-lang.org/t/static-vcruntime-distribute-windows-msvc-binaries-without-needing-to-deploy-vcruntime-dll/57599
[target.'cfg(all(windows, target_env = "msvc"))']
rustflags = [
"-C",
"link-args=/DEFAULTLIB:ucrt.lib /DEFAULTLIB:libvcruntime.lib libcmt.lib",
"-C",
"link-args=/NODEFAULTLIB:libvcruntimed.lib /NODEFAULTLIB:vcruntime.lib /NODEFAULTLIB:vcruntimed.lib",
"-C",
"link-args=/NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:msvcrtd.lib",
"-C",
"link-args=/NODEFAULTLIB:libucrt.lib /NODEFAULTLIB:libucrtd.lib /NODEFAULTLIB:ucrtd.lib",
]
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"
================================================
FILE: .editorconfig
================================================
root = true
[*]
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
[*.{json,jsonc,json5}]
indent_style = space
indent_size = 4
[*.{yml,yaml,md}]
indent_style = space
indent_size = 2
================================================
FILE: .gitattributes
================================================
* text=auto
# Ensure all lua files use LF
*.lua eol=lf
*.luau eol=lf
# Ensure all txt files within tests use LF
tests/**/*.txt eol=lf
================================================
FILE: .github/workflows/ci.yaml
================================================
name: CI
on:
push:
pull_request:
workflow_dispatch:
defaults:
run:
shell: bash
env:
CARGO_TERM_COLOR: always
jobs:
fmt:
name: Check formatting
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: Install Tooling
uses: CompeyDev/setup-rokit@v0.1.2
- name: Check Formatting
run: ./scripts/format-check.sh
analyze:
needs: ["fmt"]
name: Analyze and lint Luau files
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Tooling
uses: CompeyDev/setup-rokit@v0.1.2
- name: Analyze
run: ./scripts/analyze.sh
ci:
needs: ["fmt"]
strategy:
fail-fast: false
matrix:
include:
- name: Windows x86_64
runner-os: windows-2022
cargo-target: x86_64-pc-windows-msvc
- name: Windows aarch64
runner-os: windows-11-arm
cargo-target: aarch64-pc-windows-msvc
- name: Linux x86_64
runner-os: ubuntu-22.04
cargo-target: x86_64-unknown-linux-gnu
- name: Linux aarch64
runner-os: ubuntu-22.04-arm
cargo-target: aarch64-unknown-linux-gnu
- name: macOS x86_64
runner-os: macos-15
cargo-target: x86_64-apple-darwin
- name: macOS aarch64
runner-os: macos-15
cargo-target: aarch64-apple-darwin
name: CI - ${{ matrix.name }}
runs-on: ${{ matrix.runner-os }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: true
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
components: clippy
targets: ${{ matrix.cargo-target }}
- name: Install binstall
uses: cargo-bins/cargo-binstall@main
- name: Install nextest
run: cargo binstall cargo-nextest
- name: Build
run: |
cargo build --workspace \
--locked --all-features \
--target ${{ matrix.cargo-target }}
- name: Lint
run: |
cargo clippy --workspace \
--locked --all-features \
--target ${{ matrix.cargo-target }}
- name: Test
run: |
cargo nextest run --no-fail-fast \
--locked --all-features \
--target ${{ matrix.cargo-target }}
================================================
FILE: .github/workflows/release.yaml
================================================
name: Release
on:
workflow_dispatch:
permissions:
contents: write
defaults:
run:
shell: bash
jobs:
init:
name: Init
runs-on: ubuntu-latest
outputs:
version: ${{ steps.get_version.outputs.value }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Get version from manifest
id: get_version
run: |
PACKAGE_VERSION=$(./scripts/get-version.sh)
echo "value=${PACKAGE_VERSION}" >> $GITHUB_OUTPUT
dry-run:
name: Dry-run
needs: ["init"]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Publish (dry-run)
uses: katyo/publish-crates@v2
with:
dry-run: true
check-repo: true
registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
build:
needs: ["init", "dry-run"]
strategy:
fail-fast: false
matrix:
include:
- name: Windows x86_64
runner-os: windows-2022
artifact-name: lune-${{ needs.init.outputs.version }}-windows-x86_64
cargo-target: x86_64-pc-windows-msvc
- name: Windows aarch64
runner-os: windows-11-arm
artifact-name: lune-${{ needs.init.outputs.version }}-windows-aarch64
cargo-target: aarch64-pc-windows-msvc
- name: Linux x86_64
runner-os: ubuntu-22.04
artifact-name: lune-${{ needs.init.outputs.version }}-linux-x86_64
cargo-target: x86_64-unknown-linux-gnu
- name: Linux aarch64
runner-os: ubuntu-22.04-arm
artifact-name: lune-${{ needs.init.outputs.version }}-linux-aarch64
cargo-target: aarch64-unknown-linux-gnu
- name: macOS x86_64
runner-os: macos-15
artifact-name: lune-${{ needs.init.outputs.version }}-macos-x86_64
cargo-target: x86_64-apple-darwin
- name: macOS aarch64
runner-os: macos-15
artifact-name: lune-${{ needs.init.outputs.version }}-macos-aarch64
cargo-target: aarch64-apple-darwin
name: Build - ${{ matrix.name }}
runs-on: ${{ matrix.runner-os }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.cargo-target }}
- name: Build binary
run: |
cargo build \
--locked --all-features \
--release --target ${{ matrix.cargo-target }}
- name: Create release archive
run: ./scripts/zip-release.sh ${{ matrix.cargo-target }}
- name: Upload release artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact-name }}
path: release.zip
release-github:
name: Release (GitHub)
runs-on: ubuntu-latest
needs: ["init", "dry-run", "build"]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download releases
uses: actions/download-artifact@v4
with:
path: ./releases
- name: Unpack releases
run: ./scripts/unpack-releases.sh "./releases"
- name: Create release
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
name: ${{ needs.init.outputs.version }}
tag_name: v${{ needs.init.outputs.version }}
fail_on_unmatched_files: true
files: ./releases/*.zip
draft: true
release-crates:
name: Release (crates.io)
runs-on: ubuntu-latest
needs: ["init", "dry-run", "build"]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Publish crates
uses: katyo/publish-crates@v2
with:
dry-run: false
check-repo: true
registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
================================================
FILE: .gitignore
================================================
# Annoying macOS finder stuff
/.DS_Store
/**/.DS_Store
# Autogenerated dirs
/bin
/out
/target
/staging
/**/bin
/**/out
/**/target
/**/staging
# Autogenerated files
lune.yml
luneDocs.json
luneTypes.d.luau
# Dirs generated by runtime or build scripts
/types
# Files generated by runtime or build scripts
scripts/brick_color.rs
scripts/font_enum_map.rs
scripts/physical_properties_enum_map.rs
================================================
FILE: .gitmodules
================================================
[submodule "tests/roblox/rbx-test-files"]
path = tests/roblox/rbx-test-files
url = https://github.com/rojo-rbx/rbx-test-files
================================================
FILE: .luaurc
================================================
{
"languageMode": "strict",
"lint": {
"*": true
},
"lintErrors": false,
"typeErrors": true,
"globals": [
"warn"
],
"aliases": {
"lune": "./types/",
"tests": "./tests",
"require-tests": "./tests/require/tests"
}
}
================================================
FILE: .lune/csv_printer.luau
================================================
--> A utility script that prints out a CSV
--> file in a prettified format to stdout
local LINE_SEPARATOR = "\n"
local COMMA_SEPARATOR = ","
local fs = require("@lune/fs")
local process = require("@lune/process")
local path = process.args[1] or ".lune/data/test.csv"
assert(path ~= nil and #path > 0, "No input file path was given")
assert(not fs.isDir(path), "Input file path was a dir, not a file")
assert(fs.isFile(path), "Input file path does not exist")
-- Read all the lines of the wanted file, and then split
-- out the raw lines containing comma-separated values
local csvTable = {}
for index, rawLine in string.split(fs.readFile(path), LINE_SEPARATOR) do
if #rawLine > 0 then
csvTable[index] = string.split(rawLine, COMMA_SEPARATOR)
end
end
-- Gather the maximum widths of strings
-- for alignment & spacing in advance
local maxWidths = {}
for _, row in csvTable do
for index, value in row do
maxWidths[index] = math.max(maxWidths[index] or 0, #value)
end
end
local totalWidth = 0
local totalColumns = 0
for _, width in maxWidths do
totalWidth += width
totalColumns += 1
end
-- We have everything we need, print it out with
-- the help of some unicode box drawing characters
local thiccLine = string.rep("━", totalWidth + totalColumns * 3 - 1)
print(string.format("┏%s┓", thiccLine))
for rowIndex, row in csvTable do
local paddedValues = {}
for valueIndex, value in row do
local spacing = string.rep(" ", maxWidths[valueIndex] - #value)
table.insert(paddedValues, value .. spacing)
end
print(string.format("┃ %s ┃", table.concat(paddedValues, " ┃ ")))
-- The first line is the header, we should
-- print out an extra separator below it
if rowIndex == 1 then
print(string.format("┣%s┫", thiccLine))
end
end
print(string.format("┗%s┛", thiccLine))
================================================
FILE: .lune/data/test.csv
================================================
Header1,Header2,Header3
Hello,World,!
1,2,3
Foo,Bar,Baz
================================================
FILE: .lune/hello_lune.luau
================================================
local fs = require("@lune/fs")
local net = require("@lune/net")
local process = require("@lune/process")
local serde = require("@lune/serde")
local stdio = require("@lune/stdio")
local task = require("@lune/task")
--[[
EXAMPLE #1
Using arguments given to the program
]]
if #process.args > 0 then
print("Got arguments:")
print(process.args)
if #process.args > 3 then
error("Too many arguments!")
end
else
print("Got no arguments ☹️")
end
--[[
EXAMPLE #2
Using the stdio library to prompt for terminal input
]]
local text = stdio.prompt("text", "Please write some text")
print("You wrote '" .. text .. "'!")
local confirmed = stdio.prompt("confirm", "Please confirm that you wrote some text")
if confirmed == false then
error("You didn't confirm!")
else
print("Confirmed!")
end
--[[
EXAMPLE #3
Get & set environment variables
Checks if environment variables are empty or not,
prints out ❌ if empty and ✅ if they have a value
]]
print("Reading current environment 🔎")
-- Environment variables can be read directly
assert(process.env.PATH ~= nil, "Missing PATH")
assert(process.env.PWD ~= nil, "Missing PWD")
-- And they can also be accessed using Luau's generalized iteration (but not pairs())
for key, value in process.env do
local box = if value and value ~= "" then "✅" else "❌"
print(string.format("[%s] %s", box, key))
end
--[[
EXAMPLE #4
Spawning concurrent tasks
These tasks will run at the same time as other Lua code which lets you do primitive multitasking
]]
task.spawn(function()
print("Spawned a task that will run instantly but not block")
task.wait(5)
end)
print("Spawning a delayed task that will run in 5 seconds")
task.delay(5, function()
print("...")
task.wait(1)
print("Hello again!")
task.wait(1)
print("Goodbye again! 🌙")
end)
--[[
EXAMPLE #5
Read files in the current directory
This prints out directory & file names with some fancy icons
]]
print("Reading current dir 🗂️")
local entries = fs.readDir(".")
-- NOTE: We have to do this outside of the sort function
-- to avoid yielding across the metamethod boundary, all
-- of the filesystem APIs are asynchronous and yielding
local entryIsDir = {}
for _, entry in entries do
entryIsDir[entry] = fs.isDir(entry)
end
-- Sort prioritizing directories first, then alphabetically
table.sort(entries, function(entry0, entry1)
if entryIsDir[entry0] ~= entryIsDir[entry1] then
return entryIsDir[entry0]
end
return entry0 < entry1
end)
-- Make sure we got some known files that should always exist
assert(table.find(entries, "Cargo.toml") ~= nil, "Missing Cargo.toml")
assert(table.find(entries, "Cargo.lock") ~= nil, "Missing Cargo.lock")
-- Print the pretty stuff
for _, entry in entries do
if fs.isDir(entry) then
print("📁 " .. entry)
else
print("📄 " .. entry)
end
end
--[[
EXAMPLE #6
Call out to another program / executable
You can also get creative and combine this with example #6 to spawn several programs at the same time!
]]
print("Sending 4 pings to google 🌏")
local result = process.exec("ping", {
"google.com",
"-c 4",
})
--[[
EXAMPLE #7
Using the result of a spawned process, exiting the process
This looks scary with lots of weird symbols, but, it's just some Lua-style pattern matching
to parse the lines of "min/avg/max/stddev = W/X/Y/Z ms" that the ping program outputs to us
]]
if result.ok then
assert(#result.stdout > 0, "Result output was empty")
local min, avg, max, stddev =
string.match(result.stdout, "min/avg/max/stddev = ([%d%.]+)/([%d%.]+)/([%d%.]+)/([%d%.]+) ms")
print(string.format("Minimum ping time: %.3fms", assert(tonumber(min))))
print(string.format("Maximum ping time: %.3fms", assert(tonumber(max))))
print(string.format("Average ping time: %.3fms", assert(tonumber(avg))))
print(string.format("Standard deviation: %.3fms", assert(tonumber(stddev))))
else
print("Failed to send ping to google!")
print(result.stderr)
process.exit(result.code)
end
--[[
EXAMPLE #8
Using the built-in networking library, encoding & decoding json
]]
print("Sending PATCH request to web API 📤")
local apiResult = net.request({
url = "https://jsonplaceholder.typicode.com/posts/1",
method = "PATCH",
headers = {
["Content-Type"] = "application/json",
} :: { [string]: string },
body = serde.encode("json", {
title = "foo",
body = "bar",
}),
})
if not apiResult.ok then
print("Failed to send network request!")
print(string.format("%d (%s)", apiResult.statusCode, apiResult.statusMessage))
print(apiResult.body)
process.exit(1)
end
type ApiResponse = {
id: number,
title: string,
body: string,
userId: number,
}
local apiResponse: ApiResponse = serde.decode("json", apiResult.body)
assert(apiResponse.title == "foo", "Invalid json response")
assert(apiResponse.body == "bar", "Invalid json response")
print("Got valid JSON response with changes applied")
--[[
EXAMPLE #9
Using the stdio library to print pretty
]]
print("Printing with pretty colors and auto-formatting 🎨")
print(stdio.color("blue") .. string.rep("—", 22) .. stdio.color("reset"))
print("API response:", apiResponse)
warn({
Oh = {
No = {
TooMuch = {
Nesting = {
"Will not print",
},
},
},
},
})
print(stdio.color("blue") .. string.rep("—", 22) .. stdio.color("reset"))
--[[
EXAMPLE #10
Saying goodbye 😔
]]
print("Goodbye, lune! 🌙")
================================================
FILE: .lune/http_server.luau
================================================
--> A basic http server that echoes the given request
--> body at /ping and otherwise responds 404 "Not Found"
local net = require("@lune/net")
local process = require("@lune/process")
local PORT = if process.env.PORT ~= nil and #process.env.PORT > 0
then assert(tonumber(process.env.PORT), "Failed to parse port from env")
else 8080
-- Create our responder functions
local function root(_request: net.ServeRequest): string
return `Hello from Lune server!`
end
local function pong(request: net.ServeRequest): string
return `Pong!\n{request.path}\n{request.body}`
end
local function teapot(_request: net.ServeRequest): net.ServeResponse
return {
status = 418,
body = "🫖",
}
end
local function notFound(_request: net.ServeRequest): net.ServeResponse
return {
status = 404,
body = "Not Found",
}
end
-- Run the server on the port forever
net.serve(PORT, function(request)
if request.path == "/" then
return root(request)
elseif string.sub(request.path, 1, 5) == "/ping" then
return pong(request)
elseif string.sub(request.path, 1, 7) == "/teapot" then
return teapot(request)
else
return notFound(request)
end
end)
print(`Listening on port {PORT} 🚀`)
print("Press Ctrl+C to stop")
================================================
FILE: .lune/websocket_client.luau
================================================
--> A basic web socket client that communicates with an echo server
local net = require("@lune/net")
local process = require("@lune/process")
local task = require("@lune/task")
local PORT = if process.env.PORT ~= nil and #process.env.PORT > 0
then assert(tonumber(process.env.PORT), "Failed to parse port from env")
else 8080
local URL = `ws://127.0.0.1:{PORT}`
-- Connect to our web socket server
local socket = net.socket(URL)
print("Connected to echo web socket server at '" .. URL .. "'")
print("Sending a message every second for 5 seconds...")
-- Force exit after 10 seconds in case the server is not responding well
local forceExit = task.delay(10, function()
warn("Example did not complete in time, exiting...")
process.exit(1)
end)
-- Send one message per second and time it
for _ = 1, 5 do
local start = os.clock()
socket:send(tostring(1))
local response = socket:next()
local elapsed = os.clock() - start
print(`Got response '{response}' in {elapsed * 1_000} milliseconds`)
task.wait(1 - elapsed)
end
-- Everything went well, and we are done with the socket, so we can close it
print("Closing web socket...")
socket:close()
task.cancel(forceExit)
print("Done! 🌙")
================================================
FILE: .lune/websocket_server.luau
================================================
--> A basic web socket server that echoes given messages
local net = require("@lune/net")
local process = require("@lune/process")
local task = require("@lune/task")
local PORT = if process.env.PORT ~= nil and #process.env.PORT > 0
then assert(tonumber(process.env.PORT), "Failed to parse port from env")
else 8080
-- Run the server on port 8080, if we get a normal http request on
-- the port this will respond with 426 Upgrade Required by default
local handle = net.serve(PORT, {
handleWebSocket = function(socket)
print("Got new web socket connection!")
repeat
local message = socket:next()
if message ~= nil then
socket:send("Echo - " .. message)
end
until message == nil
print("Web socket disconnected.")
end,
})
print(`Listening on port {PORT} 🚀`)
-- Exit our example after a small delay, if you copy this
-- example just remove this part to keep the server running
task.delay(10, function()
print("Shutting down...")
task.wait(1)
handle.stop()
task.wait(1)
end)
================================================
FILE: .vscode/extensions.json
================================================
{
"recommendations": [
"rust-lang.rust-analyzer",
"esbenp.prettier-vscode",
"JohnnyMorganz.stylua",
"DavidAnson.vscode-markdownlint"
]
}
================================================
FILE: .vscode/settings.json
================================================
{
"luau-lsp.sourcemap.enabled": false,
"luau-lsp.types.roblox": false,
"luau-lsp.ignoreGlobs": [
"tests/roblox/rbx-test-files/**/*.lua",
"tests/roblox/rbx-test-files/**/*.luau"
],
"rust-analyzer.check.command": "clippy",
"editor.formatOnSave": true,
"stylua.searchParentDirectories": true,
"prettier.tabWidth": 2,
"[luau][lua]": {
"editor.defaultFormatter": "JohnnyMorganz.stylua"
},
"[json][jsonc][markdown][yaml]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer"
}
}
================================================
FILE: CHANGELOG.md
================================================
<!-- markdownlint-disable MD023 -->
<!-- markdownlint-disable MD033 -->
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## `0.10.4` - October 14th, 2025
### Added
- Added support for the `jsonc` serialization format in the `serde` standard library
- Added an `mlua` feature flag to `lune-roblox`, so that it may be used from Rust without bundling the entirety of Luau
### Changed
- Updated to rbx-dom database version `0.694`
- Updated to Luau version `0.694`
### Fixed
- Fixed attribute name validation being too strict in the `roblox` standard library, not allowing the characters `/.-`
- Fixed various issues in the `roblox` standard library caused by an outdated reflection database and version of `rbx-dom` ([#358])
[#358]: https://github.com/lune-org/lune/pull/358
## `0.10.3` - October 6th, 2025
### Changed
- Updated to Luau version `0.693`
### Fixed
- Fixed `readToEnd` being slow for child processes with large output ([#354])
- Fixed `process.exec` not reading stdio until child exits ([#353])
[#354]: https://github.com/lune-org/lune/pull/354
[#353]: https://github.com/lune-org/lune/pull/353
## `0.10.2` - August 31st, 2025
### Added
- Added support for the ZSTD compression format in the `serde` standard library ([#339])
- Added support for `UniqueId` properties to the `roblox` standard library ([#343])
- Added prebuilt Lune binaries for Windows on ARM to GitHub releases
### Changed
- Updated to Luau version `0.688`
- Lune no longer depends on `liblzma`, making it easier to install on macOS
- Prebuilt binaries for Ubuntu now use an older version (22.04) for better GLIBC compatibility
### Fixed
- Fixed Lune crashing while emitting an error and parsing its source
[#339]: https://github.com/lune-org/lune/pull/339
[#343]: https://github.com/lune-org/lune/pull/343
## `0.10.1` - July 16th, 2025
### Fixed
- Fixed a regression where it was not possible to run directories with `init.luau` files in them directly using `lune run directory-name`.
- Fixed a panic when calling `process.exit` inside a file that `require` was called on. ([#333])
- Fixed a panic when calling `process.exit` inside a request handler for `net.serve`. ([#333])
[#333]: https://github.com/lune-org/lune/pull/333
## `0.10.0` - July 15th, 2025
This version of Lune contains a major internal refactoring of the `require` function, now using the proper require-by-string APIs exposed by Luau.
If you relied on any (incorrect) behavior of relative, non-`@self` requires, from within `init.luau` files in Lune `0.9.0`, you may need to update your code.
No other usages of `require` will be affected - but if you previously encountered any internal bugs or panics during `require`, these will have been fixed!
### Added
- Added support for TCP client in the `net` standard library.
It may be used either with TLS or not, and basic usage looks as such:
```luau
-- Plain TCP connections
local stream = net.tcp.connect("example.com", 80)
-- TLS connections (shorthand)
local tlsStream = net.tcp.connect("example.com", 443, true)
-- Connections with custom TLS setting & TTL
local customStream = net.tcp.connect("192.168.1.100", 8080, {
tls = false,
ttl = 128
})
-- Interacting with the stream
tlsStream:write("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
while true do
local data = tlsStream:read()
if data ~= nil then
print(data)
else
break -- Connection was closed
end
end
```
- Added submodules to the `net` standard library: `http`, `tcp`, and `ws`.
These will be the preferred way of interacting with the `net` standard library going forward, but none of the old functions have been removed or deprecated yet to allow users time to migrate.
In a future major version of Lune, direct functions such as `net.socket` will be removed in favor of their equivalent functions in submodules, such as `net.ws.connect`. Here is the full new list of functions:
- `net.http.request`
- `net.http.serve`
- `net.tcp.connect`
- `net.ws.connect`
- Added a method `with_lib` to the `Runtime` struct in the `lune` crate, to allow registering custom libraries.
### Changed
- Updated to Luau version `0.682`
- Upgraded to `mlua` version `0.11` - if you use any of the Lune crates as a dependency, you may also need to upgrade
### Fixed
- Fixed errors being emitted twice when the error is thrown from the main (entrypoint) script
- Fixed a panic when calling `net.request` and related functions in the main body of a module during `require`
- Fixed various issues with not conforming to the new Luau require-by-string semantics
## `0.9.4` - June 13th, 2025
### Changed
- `lune setup` now properly sets up a `.luaurc` file instead of using legacy VSCode-specific settings
- `process.args` and `process.env` are now plain tables again - _not userdata_ - thank you to everyone who provided feedback on this and the usability issues!
### Fixed
- Fixed invalid handling of http redirects in `net.request`
- Fixed not being able to download binaries for cross-compiling with `lune build`
- Fixed binary output when running `lune build` not being deterministic and sometimes truncating
- Fixed `cargo install lune` failing due to a yanked dependency ([#323])
[#323]: https://github.com/lune-org/lune/pull/323
## `0.9.3` - May 6th, 2025
### Added
- Added support for non-UTF8 strings in arguments to `process.exec` and `process.spawn`
### Changed
- Improved cross-platform compatibility and correctness for values in `process.args` and `process.env`, especially on Windows
### Fixed
- Fixed stdin not being properly closed when not providing the stdin option to `process.exec`
- Fixed various crashes during require that had the error `cannot mutably borrow app data container`
## `0.9.2` - April 30th, 2025
### Changed
- Improved performance of `net.request` and `net.serve` when handling large request bodies
- Improved performance and memory usage of `task.spawn`, `task.defer`, and `task.delay`
### Fixed
- Fixed accidental breakage of `net.request` in version `0.9.1`
## `0.9.1` - April 29th, 2025
### Added
- Added support for automatic decompression of HTTP requests in `net.serve` ([#310])
### Fixed
- Fixed `net.serve` no longer serving requests if the returned `ServeHandle` is discarded ([#310])
- Fixed `net.serve` having various performance issues ([#310])
- Fixed Lune still running after cancelling a task such as `task.delay(5, ...)` and all tasks having completed
[#310]: https://github.com/lune-org/lune/pull/310
## `0.9.0` - April 25th, 2025
The next major version of Lune has finally been released!
This release has been a long time coming, and many breaking changes have been made.
If you are an existing Lune user upgrading to this version, you will **most likely** be affected.
The full list of breaking changes can be found on below.
### Breaking changes & additions
- The behavior of `require` has changed, according to the latest Luau RFCs and specifications.
For the full details, feel free to read documentation [here](https://github.com/luau-lang/rfcs), otherwise, the most notable changes here are:
- Paths passed to require must start with either `./`, `../` or `@` - require statements such as `require("foo")` **will now error** and must be changed to `require("./foo")`.
- The behavior of require from within `init.luau` and `init.lua` files has changed - previously `require("./foo")` would resolve
to the file or directory `foo` _as a **sibling** of the init file_, but will now resolve to the file or directory `foo` _which is a sibling of the **parent directory** of the init file_.
To require files inside of the same directory as the init file, the new `@self` alias must be used - like `require("@self/foo")`.
- The main `lune run` subcommand will no longer sink flags passed to it - `lune run --` will now _literally_ pass the string `--` as the first
value in `process.args`, and `--` is no longer necessary to be able to pass flag arguments such as `--foo` and `-b` properly to your Lune programs.
- Two new process spawning functions - `process.create` and `process.exec` - replace the previous `process.spawn` API. ([#211])
To migrate from `process.spawn`, use the new `process.exec` API which retains the same behavior as the old function, with slight changes in how the `stdin` option is passed.
The new `process.create` function is a non-blocking process creation API and can be used to interactively
read and write to standard input and output streams of the child process.
```lua
local child = process.create("program", {
"first-argument",
"second-argument"
})
-- Writing to stdin
child.stdin:write("Hello from Lune!")
-- Reading partial data from stdout
local data = child.stdout:read()
print(data)
-- Reading the full stdout
local full = child.stdout:readToEnd()
print(full)
```
- Removed `net.jsonEncode` and `net.jsonDecode` - please use the equivalent `serde.encode("json", ...)` and `serde.decode("json", ...)` instead
- WebSocket methods in `net.socket` and `net.serve` now use standard Lua method calling convention and colon syntax.
This means `socket.send(...)` is now `socket:send(...)`, `socket.close(...)` is now `socket:close(...)`, and so on.
- Various changes have been made to the Lune Rust crates:
- `Runtime::run` now returns a more useful value instead of an `ExitCode` ([#178])
- All Lune standard library crates now export a `typedefs` function that returns the source code for the respective standard library module type definitions
- All Lune crates now depend on `mlua` version `0.10` or above
- Most Lune crates have been migrated to the `smol` and `async-*` ecosystem instead of `tokio`, with a full migration expected soon (this will not break public types)
- The `roblox` crate re-export has been removed from the main `lune` crate - please depend on `lune-roblox` crate directly instead
### Added
- Added functions for getting Roblox Studio locations to the `roblox` standard library ([#284])
- Added support for the `Content` datatype in the `roblox` standard library ([#305])
- Added support for `EnumItem` instance attributes in the `roblox` standard library ([#306])
- Added support for RFC 2822 dates in the `datetime` standard library using `fromRfc2822` ([#285]) - the `fromIsoDate`
function has also been deprecated (not removed yet) and `fromRfc3339` should instead be preferred for any new work.
- Added a `readLine` function to the `stdio` standard library for reading line-by-line from stdin.
- Added a way to disable JIT by setting the `LUNE_LUAU_JIT` environment variable to `false` before running Lune.
- Added `process.endianness` constant ([#267])
### Changed
- Documentation comments for several standard library properties have been improved ([#248], [#250])
- Error messages no longer contain redundant or duplicate stack trace information
- Updated to Luau version `0.663`
- Updated to rbx-dom database version `0.670`
### Fixed
- Fixed deadlock in `stdio.format` calls in `__tostring` metamethods ([#288])
- Fixed `task.wait` and `task.delay` not being guaranteed to yield when duration is set to zero or very small values
- Fixed `__tostring` metamethods sometimes not being respected in `print` and `stdio.format` calls
[#178]: https://github.com/lune-org/lune/pull/178
[#211]: https://github.com/lune-org/lune/pull/211
[#248]: https://github.com/lune-org/lune/pull/248
[#250]: https://github.com/lune-org/lune/pull/250
[#265]: https://github.com/lune-org/lune/pull/265
[#267]: https://github.com/lune-org/lune/pull/267
[#284]: https://github.com/lune-org/lune/pull/284
[#285]: https://github.com/lune-org/lune/pull/285
[#288]: https://github.com/lune-org/lune/pull/288
[#305]: https://github.com/lune-org/lune/pull/305
[#306]: https://github.com/lune-org/lune/pull/306
## `0.8.9` - October 7th, 2024
### Changed
- Updated to Luau version `0.640`
## `0.8.8` - August 22nd, 2024
### Fixed
- Fixed errors when deserializing `Lighting.AttributesSerialize` by updating `rbx-dom` dependencies ([#245])
[#245]: https://github.com/lune-org/lune/pull/245
## `0.8.7` - August 10th, 2024
### Added
- Added a compression level option to `serde.compress` ([#224])
- Added missing vector methods to the `roblox` library ([#228])
### Changed
- Updated to Luau version `0.635`
- Updated to rbx-dom database version `0.634`
### Fixed
- Fixed `fs.readDir` with trailing forward-slash on Windows ([#220])
- Fixed `__type` and `__tostring` metamethods not always being respected when formatting tables
[#220]: https://github.com/lune-org/lune/pull/220
[#224]: https://github.com/lune-org/lune/pull/224
[#228]: https://github.com/lune-org/lune/pull/228
## `0.8.6` - June 23rd, 2024
### Added
- Added a builtin API for hashing and calculating HMACs as part of the `serde` library ([#193])
Basic usage:
```lua
local serde = require("@lune/serde")
local hash = serde.hash("sha256", "a message to hash")
local hmac = serde.hmac("sha256", "a message to hash", "a secret string")
print(hash)
print(hmac)
```
The returned hashes are sequences of lowercase hexadecimal digits. The following algorithms are supported:
`md5`, `sha1`, `sha224`, `sha256`, `sha384`, `sha512`, `sha3-224`, `sha3-256`, `sha3-384`, `sha3-512`, `blake3`
- Added two new options to `luau.load`:
- `codegenEnabled` - whether or not codegen should be enabled for the loaded chunk.
- `injectGlobals` - whether or not to inject globals into a passed `environment`.
By default, globals are injected and codegen is disabled.
Check the documentation for the `luau` standard library for more information.
- Implemented support for floor division operator / `__idiv` for the `Vector2` and `Vector3` types in the `roblox` standard library ([#196])
- Fixed the `_VERSION` global containing an incorrect Lune version string.
### Changed
- Sandboxing and codegen in the Luau VM is now fully enabled, resulting in up to 2x or faster code execution.
This should not result in any behavior differences in Lune, but if it does, please open an issue.
- Improved formatting of custom error objects (such as when `fs.readFile` returns an error) when printed or formatted using `stdio.format`.
### Fixed
- Fixed `__type` and `__tostring` metamethods on userdatas and tables not being respected when printed or formatted using `stdio.format`.
[#193]: https://github.com/lune-org/lune/pull/193
[#196]: https://github.com/lune-org/lune/pull/196
## `0.8.5` - June 1st, 2024
### Changed
- Improved table pretty formatting when using `print`, `warn`, and `stdio.format`:
- Keys are sorted numerically / alphabetically when possible.
- Keys of different types are put in distinct sections for mixed tables.
- Tables that are arrays no longer display their keys.
- Empty tables are no longer spread across lines.
## Fixed
- Fixed formatted values in tables not being separated by newlines.
- Fixed panicking (crashing) when using `process.spawn` with a program that does not exist.
- Fixed `instance:SetAttribute("name", nil)` throwing an error and not removing the attribute.
## `0.8.4` - May 12th, 2024
### Added
- Added a builtin API for regular expressions.
Example basic usage:
```lua
local Regex = require("@lune/regex")
local re = Regex.new("hello")
if re:isMatch("hello, world!") then
print("Matched!")
end
local caps = re:captures("hello, world! hello, again!")
print(#caps) -- 2
print(caps:get(1)) -- "hello"
print(caps:get(2)) -- "hello"
print(caps:get(3)) -- nil
```
Check out the documentation for more details.
- Added support for buffers as arguments in builtin APIs ([#148])
This includes APIs such as `fs.writeFile`, `serde.encode`, and more.
- Added support for cross-compilation of standalone binaries ([#162])
You can now compile standalone binaries for other platforms by passing
an additional `target` argument to the `build` subcommand:
```sh
lune build my-file.luau --output my-bin --target windows-x86_64
```
Currently supported targets are the same as the ones included with each
release of Lune on GitHub. Check releases for a full list of targets.
- Added `stdio.readToEnd()` for reading the entire stdin passed to Lune
### Changed
- Split the repository into modular crates instead of a monolith. ([#188])
If you previously depended on Lune as a crate, nothing about it has changed for version `0.8.4`, but now each individual sub-crate has also been published and is available for use:
- `lune` (old)
- `lune-utils`
- `lune-roblox`
- `lune-std-*` for every builtin library
When depending on the main `lune` crate, each builtin library also has a feature flag that can be toggled in the format `std-*`.
In general, this should mean that it is now much easier to make your own Lune builtin, publish your own flavor of a Lune CLI, or take advantage of all the work that has been done for Lune as a runtime when making your own Rust programs.
- Changed the `User-Agent` header in `net.request` to be more descriptive ([#186])
- Updated to Luau version `0.622`.
### Fixed
- Fixed not being able to decompress `lz4` format in high compression mode
- Fixed stack overflow for tables with circular keys ([#183])
- Fixed `net.serve` no longer accepting ipv6 addresses
- Fixed headers in `net.serve` being raw bytes instead of strings
[#148]: https://github.com/lune-org/lune/pull/148
[#162]: https://github.com/lune-org/lune/pull/162
[#183]: https://github.com/lune-org/lune/pull/183
[#186]: https://github.com/lune-org/lune/pull/186
[#188]: https://github.com/lune-org/lune/pull/188
## `0.8.3` - April 15th, 2024
### Fixed
- Fixed `require` not throwing syntax errors ([#168])
- Fixed `require` caching not working correctly ([#171])
- Fixed case-sensitivity issue in `require` with aliases ([#173])
- Fixed `itertools` dependency being marked optional even though it is mandatory ([#176])
- Fixed test cases for the `net` built-in library on Windows ([#177])
[#168]: https://github.com/lune-org/lune/pull/168
[#171]: https://github.com/lune-org/lune/pull/171
[#173]: https://github.com/lune-org/lune/pull/173
[#176]: https://github.com/lune-org/lune/pull/176
[#177]: https://github.com/lune-org/lune/pull/177
## `0.8.2` - March 12th, 2024
### Fixed
- Fixed REPL panicking after the first evaluation / run.
- Fixed globals reloading on each run in the REPL, causing unnecessary slowdowns.
- Fixed `net.serve` requests no longer being plain tables in Lune `0.8.1`, breaking usage of things such as `table.clone`.
## `0.8.1` - March 11th, 2024
### Added
- Added the ability to specify an address in `net.serve`. ([#142])
### Changed
- Update to Luau version `0.616`.
- Major performance improvements when using a large amount of threads / asynchronous Lune APIs. ([#165])
- Minor performance improvements and less overhead for `net.serve` and `net.socket`. ([#165])
### Fixed
- Fixed `fs.copy` not working with empty dirs. ([#155])
- Fixed stack overflow when printing tables with cyclic references. ([#158])
- Fixed not being able to yield in `net.serve` handlers without blocking other requests. ([#165])
- Fixed various scheduler issues / panics. ([#165])
[#142]: https://github.com/lune-org/lune/pull/142
[#155]: https://github.com/lune-org/lune/pull/155
[#158]: https://github.com/lune-org/lune/pull/158
[#165]: https://github.com/lune-org/lune/pull/165
## `0.8.0` - January 14th, 2024
### Breaking Changes
- The Lune CLI now uses subcommands instead of flag options: <br/>
- `lune script_name arg1 arg2 arg3` -> `lune run script_name arg1 arg2 arg3`
- `lune --list` -> `lune list`
- `lune --setup` -> `lune setup`
This unfortunately hurts ergonomics for quickly running scripts but is a necessary change to allow us to add more commands, such as the new `build` subcommand.
- The `createdAt`, `modifiedAt`, and `accessedAt` properties returned from `fs.metadata` are now `DateTime` values instead of numbers.
- The `Lune` struct has been renamed to `Runtime` in the Lune rust crate.
### Added
- Added support for compiling single Lune scripts into standalone executables! ([#140])
Example usage:
```lua
-- my_cool_script.luau
print("Hello, standalone!")
```
```sh
> lune build my_cool_script.luau
# Creates `my_cool_script.exe` (Windows) or `my_cool_script` (macOS / Linux)
```
```sh
> ./my_cool_script.exe # Windows
> ./my_cool_script # macOS / Linux
> "Hello, standalone!"
```
To compile scripts that use `require` and reference multiple files, a bundler such as [darklua](https://github.com/seaofvoices/darklua) should preferrably be used. You may also distribute files alongside the standalone binary, they will still be able to be `require`-d. This limitation will be lifted in the future and Lune will automatically bundle any referenced scripts.
- Added support for path aliases using `.luaurc` config files!
For full documentation and reference, check out the [official Luau RFC](https://rfcs.luau-lang.org/require-by-string-aliases.html), but here's a quick example:
```jsonc
// .luaurc
{
"aliases": {
"modules": "./some/long/path/to/modules",
},
}
```
```lua
-- ./some/long/path/to/modules/foo.luau
return { World = "World!" }
-- ./anywhere/you/want/my_script.luau
local mod = require("@modules/foo")
print("Hello, " .. mod.World)
```
- Added support for multiple values for a single query, and multiple values for a single header, in `net.request`. This is a part of the HTTP specification that is not widely used but that may be useful in certain cases. To clarify:
- Single values remain unchanged and will work exactly the same as before. <br/>
```lua
-- https://example.com/?foo=bar&baz=qux
local net = require("@lune/net")
net.request({
url = "example.com",
query = {
foo = "bar",
baz = "qux",
}
})
```
- Multiple values _on a single query / header_ are represented as an ordered array of strings. <br/>
```lua
-- https://example.com/?foo=first&foo=second&foo=third&bar=baz
local net = require("@lune/net")
net.request({
url = "example.com",
query = {
foo = { "first", "second", "third" },
bar = "baz",
}
})
```
[#140]: https://github.com/lune-org/lune/pull/140
### Changed
- Update to Luau version `0.606`.
### Fixed
- Fixed the `print` and `warn` global functions yielding the thread, preventing them from being used in places such as the callback to `table.sort`.
- Fixed the `overwrite` option for `fs.move` not correctly removing existing files / directories. ([#133])
[#133]: https://github.com/lune-org/lune/pull/133
## `0.7.11` - October 29th, 2023
### Changed
- Update to Luau version `0.601`.
### Fixed
- Fixed `roblox.getAuthCookie` not being compatible with the latest cookie format by upgrading rbx_cookie.
## `0.7.10` - October 25th, 2023
### Added
- Added the `GetDebugId` instance method to the `roblox` built-in. This will return the internal id used by the instance, and as the name implies, it should be primarily used for _debugging_ purposes and cases where you need a globally unique identifier for an instance. It is guaranteed to be a 32-digit hexadecimal string.
### Fixed
- Fixed issues with `SecurityCapabilities` on instances in the `roblox` built-in by upgrading rbx-dom.
## `0.7.9` - October 21st, 2023
### Added
- Added `implementProperty` and `implementMethod` to the `roblox` built-in library to fill in missing functionality that Lune does not aim to implement itself.
Example usage:
```lua
local roblox = require("@lune/roblox")
local part = roblox.Instance.new("Part")
roblox.implementMethod("BasePart", "TestMethod", function(_, ...)
print("Tried to call TestMethod with", ...)
end)
part:TestMethod("Hello", "world!")
```
### Changed
- Update to Luau version `0.599`.
- Stdio options when using `process.spawn` can now be set with more granularity, allowing stderr & stdout to be disabled individually and completely to improve memory usage when they are not being used.
## `0.7.8` - October 5th, 2023
### Added
- Added a new `datetime` built-in library for handling date & time values, parsing, formatting, and more. ([#94])
Example usage:
```lua
local DateTime = require("@lune/datetime")
-- Creates a DateTime for the current exact moment in time
local now = DateTime.now()
-- Formats the current moment in time as an ISO 8601 string
print(now:toIsoDate())
-- Formats the current moment in time, using the local
-- time, the French locale, and the specified time string
print(now:formatLocalTime("%A, %d %B %Y", "fr"))
-- Returns a specific moment in time as a DateTime instance
local someDayInTheFuture = DateTime.fromLocalTime({
year = 3033,
month = 8,
day = 26,
hour = 16,
minute = 56,
second = 28,
millisecond = 892,
})
-- Extracts the current local date & time as separate values (same values as above table)
print(now:toLocalTime())
-- Returns a DateTime instance from a given float, where the whole
-- denotes the seconds and the fraction denotes the milliseconds
-- Note that the fraction for millis here is completely optional
DateTime.fromUnixTimestamp(871978212313.321)
-- Extracts the current universal (UTC) date & time as separate values
print(now:toUniversalTime())
```
- Added support for passing `stdin` in `process.spawn` ([#106])
- Added support for setting a custom environment in load options for `luau.load`, not subject to `getfenv` / `setfenv` deoptimizations
- Added [Terrain:GetMaterialColor](https://create.roblox.com/docs/reference/engine/classes/Terrain#GetMaterialColor) and [Terrain:SetMaterialColor](https://create.roblox.com/docs/reference/engine/classes/Terrain#SetMaterialColor) ([#93])
- Added support for a variable number of arguments for CFrame methods ([#85])
### Changed
- Update to Luau version `0.596`.
- Update to rbx-dom database version `0.596`.
- `process.spawn` now uses `powershell` instead of `/bin/bash` as the shell on Windows, with `shell = true`.
- CFrame and Vector3 values are now rounded to the nearest 2 ^ 16 decimal place to reduce floating point errors and diff noise. Note that this does not affect intermediate calculations done in lua, and only happens when a property value is set on an Instance.
### Fixed
- Fixed the `process` built-in library not loading correctly when using Lune in REPL mode.
- Fixed list subcommand not listing global scripts without a local `.lune` / `lune` directory present.
- Fixed `net.serve` stopping when the returned `ServeHandle` is garbage collected.
- Fixed missing trailing newline when using the `warn` global.
- Fixed constructor for `CFrame` in the `roblox` built-in library not parsing the 12-arg overload correctly. ([#102])
- Fixed various functions for `CFrame` in the `roblox` built-in library being incorrect, specifically row-column ordering and some flipped signs. ([#103])
- Fixed cross-service Instance references disappearing when using the `roblox` built-in library ([#117])
[#85]: https://github.com/lune-org/lune/pull/85
[#93]: https://github.com/lune-org/lune/pull/93
[#94]: https://github.com/lune-org/lune/pull/94
[#102]: https://github.com/lune-org/lune/pull/102
[#103]: https://github.com/lune-org/lune/pull/103
[#106]: https://github.com/lune-org/lune/pull/106
[#117]: https://github.com/lune-org/lune/pull/117
## `0.7.7` - August 23rd, 2023
### Added
- Added a [REPL](https://en.wikipedia.org/wiki/Read–eval–print_loop) to Lune. ([#83])
This allows you to run scripts within Lune without writing files!
Example usage, inside your favorite terminal:
```bash
# 1. Run the Lune executable, without any arguments
lune
# 2. You will be shown the current Lune version and a blank prompt arrow:
Lune v0.7.7
>
# 3. Start typing, and hit enter when you want to run your script!
# Your script will run until completion and output things along the way.
> print(2 + 3)
5
> print("Hello, lune changelog!")
Hello, lune changelog!
# 4. You can also set variables that will get preserved between runs.
# Note that local variables do not get preserved here.
> myVariable = 123
> print(myVariable)
123
# 5. Press either of these key combinations to exit the REPL:
# - Ctrl + D
# - Ctrl + C
```
- Added a new `luau` built-in library for manually compiling and loading Luau source code. ([#82])
Example usage:
```lua
local luau = require("@lune/luau")
local bytecode = luau.compile("print('Hello, World!')")
local callableFn = luau.load(bytecode)
callableFn()
-- Additionally, we can skip the bytecode generation and
-- load a callable function directly from the code itself.
local callableFn2 = luau.load("print('Hello, World!')")
callableFn2()
```
### Changed
- Update to Luau version `0.591`.
- Lune's internal task scheduler and `require` functionality has been completely rewritten. <br/>
The new scheduler is much more stable, conforms to a larger test suite, and has a few additional benefits:
- Built-in libraries are now lazily loaded, meaning nothing gets allocated until the built-in library gets loaded using `require("@lune/builtin-name")`. This also improves startup times slightly.
- Spawned processes using `process.spawn` now run on different thread(s), freeing up resources for the main thread where luau runs.
- Serving requests using `net.serve` now processes requests on background threads, also freeing up resources. In the future, this will also allow us to offload heavy tasks such as compression/decompression to background threads.
- Groundwork for custom / user-defined require aliases has been implemented, as well as absolute / cwd-relative requires. These will both be exposed as options and be made available to use some time in the future.
- When using the `serde` built-in library, keys are now sorted during serialization. This means that the output of `encode` is now completely deterministic, and wont cause issues when committing generated files to git etc.
### Fixed
- Fixed not being able to pass arguments to the thread using `coroutine.resume`. ([#86])
- Fixed a large number of long-standing issues, from the task scheduler rewrite:
- Fixed `require` hanging indefinitely when the module being require-d uses an async function in its main body.
- Fixed background tasks (such as `net.serve`) not keeping Lune alive even if there are no lua threads to run.
- Fixed spurious panics and error messages such as `Tried to resume next queued future but none are queued`.
- Fixed not being able to catch non-string errors properly, errors were accidentally being wrapped in an opaque `userdata` type.
[#82]: https://github.com/lune-org/lune/pull/82
[#83]: https://github.com/lune-org/lune/pull/83
[#86]: https://github.com/lune-org/lune/pull/86
## `0.7.6` - August 9th, 2023
### Changed
- Update to Luau version `0.588`
- Enabled Luau JIT backend for potential performance improvements 🚀 <br/>
If you run into any strange behavior please open an issue!
### Fixed
- Fixed publishing of the Lune library to `crates.io`
- Fixed `serde.decode` deserializing `null` values as `userdata` instead of `nil`.
- Fixed not being able to require files with multiple extensions, eg. `module.spec.luau` was not require-able using `require("module.spec")`.
- Fixed instances and `roblox` built-in library APIs erroring when used asynchronously/concurrently.
## `0.7.5` - July 22nd, 2023
### Added
- Lune now has a new documentation site! </br>
This addresses new APIs from version `0.7.0` not being available on the docs site, brings much improved searching functionality, and will help us keep documentation more up-to-date going forward with a more automated process. You can check out the new site at [lune-org.github.io](https://lune-org.github.io/docs).
- Added `fs.copy` to recursively copy files and directories.
Example usage:
```lua
local fs = require("@lune/fs")
fs.writeDir("myCoolDir")
fs.writeFile("myCoolDir/myAwesomeFile.json", "{}")
fs.copy("myCoolDir", "myCoolDir2")
assert(fs.isDir("myCoolDir2"))
assert(fs.isFile("myCoolDir2/myAwesomeFile.json"))
assert(fs.readFile("myCoolDir2/myAwesomeFile.json") == "{}")
```
- Added `fs.metadata` to get metadata about files and directories.
Example usage:
```lua
local fs = require("@lune/fs")
fs.writeFile("myAwesomeFile.json", "{}")
local meta = fs.metadata("myAwesomeFile.json")
print(meta.exists) --> true
print(meta.kind) --> "file"
print(meta.createdAt) --> 1689848548.0577152 (unix timestamp)
print(meta.permissions) --> { readOnly: false }
```
- Added `roblox.getReflectionDatabase` to access the builtin database containing information about classes and enums.
Example usage:
```lua
local roblox = require("@lune/roblox")
local db = roblox.getReflectionDatabase()
print("There are", #db:GetClassNames(), "classes in the reflection database")
print("All base instance properties:")
local class = db:GetClass("Instance")
for name, prop in class.Properties do
print(string.format(
"- %s with datatype %s and default value %s",
prop.Name,
prop.Datatype,
tostring(class.DefaultProperties[prop.Name])
))
end
```
- Added support for running directories with an `init.luau` or `init.lua` file in them in the CLI.
### Changed
- Update to Luau version `0.583`
### Fixed
- Fixed publishing of Lune to crates.io by migrating away from a monorepo.
- Fixed crashes when writing a very deeply nested `Instance` to a file. ([#62])
- Fixed not being able to read & write to WebSocket objects at the same time. ([#68])
- Fixed tab character at the start of a script causing it not to parse correctly. ([#72])
[#62]: https://github.com/lune-org/lune/pull/62
[#68]: https://github.com/lune-org/lune/pull/66
[#72]: https://github.com/lune-org/lune/pull/72
## `0.7.4` - July 7th, 2023
### Added
- Added support for `CFrame` and `Font` types in attributes when using the `roblox` builtin.
### Fixed
- Fixed `roblox.serializeModel` still keeping some unique ids.
## `0.7.3` - July 5th, 2023
### Changed
- When using `roblox.serializeModel`, Lune will no longer keep internal unique ids. <br/>
This is consistent with what Roblox does and prevents Lune from always generating a new and unique file. <br/>
This previously caused unnecessary diffs when using git or other kinds of source control. ([Relevant issue](https://github.com/lune-org/lune/issues/61))
## `0.7.2` - June 28th, 2023
### Added
- Added support for `init` files in directories, similar to Rojo, or `index.js` / `mod.rs` in JavaScript / Rust. <br/>
This means that placing a file named `init.luau` or `init.lua` in a directory will now let you `require` that directory.
### Changed
- The `lune --setup` command is now much more user-friendly.
- Update to Luau version `0.581`
## `0.7.1` - June 17th, 2023
### Added
- Added support for TLS in websockets, enabling usage of `wss://`-prefixed URLs. ([#57])
### Fixed
- Fixed `closeCode` erroring when being accessed on websockets. ([#57])
- Fixed issues with `UniqueId` when using the `roblox` builtin by downgrading `rbx-dom`.
[#57]: https://github.com/lune-org/lune/pull/57
## `0.7.0` - June 12th, 2023
### Breaking Changes
- Globals for the `fs`, `net`, `process`, `stdio`, and `task` builtins have been removed, and the `require("@lune/...")` syntax is now the only way to access builtin libraries. If you have previously been using a global such as `fs` directly, you will now need to put `local fs = require("@lune/fs")` at the top of the file instead.
- Migrated several functions in the `roblox` builtin to new, more flexible APIs:
- `readPlaceFile -> deserializePlace`
- `readModelFile -> deserializeModel`
- `writePlaceFile -> serializePlace`
- `writeModelFile -> serializeModel`
These new APIs **_no longer use file paths_**, meaning to use them with files you must first read them using the `fs` builtin.
- Removed `CollectionService` and its methods from the `roblox` builtin library - new instance methods have been added as replacements.
- Removed [`Instance:FindFirstDescendant`](https://create.roblox.com/docs/reference/engine/classes/Instance#FindFirstDescendant) which was a method that was never enabled in the official Roblox API and will soon be removed. <br/>
Use the second argument of the already existing find methods instead to find descendants.
- Removed the global `printinfo` function - it was generally not used, and did not work as intended. Use the `stdio` builtin for formatting and logging instead.
- Removed support for Windows on ARM - it's more trouble than its worth right now, we may revisit it later.
### Added
- Added `serde.compress` and `serde.decompress` for compressing and decompressing strings using one of several compression formats: `brotli`, `gzip`, `lz4`, or `zlib`.
Example usage:
```lua
local INPUT = string.rep("Input string to compress", 16) -- Repeated string 16 times for the purposes of this example
local serde = require("@lune/serde")
local compressed = serde.compress("gzip", INPUT)
local decompressed = serde.decompress("gzip", compressed)
assert(decompressed == INPUT)
```
- Added automatic decompression for compressed responses when using `net.request`.
This behavior can be disabled by passing `options = { decompress = false }` in request params.
- Added support for finding scripts in the current home directory.
This means that if you have a script called `script-name.luau`, you can place it in the following location:
- `C:\Users\YourName\.lune\script-name.luau` (Windows)
- `/Users/YourName/.lune/script-name.luau` (macOS)
- `/home/YourName/.lune/script-name.luau` (Linux)
And then run it using `lune script-name` from any directory you are currently in.
- Added several new instance methods in the `roblox` builtin library:
- [`Instance:AddTag`](https://create.roblox.com/docs/reference/engine/classes/Instance#AddTag)
- [`Instance:GetTags`](https://create.roblox.com/docs/reference/engine/classes/Instance#GetTags)
- [`Instance:HasTag`](https://create.roblox.com/docs/reference/engine/classes/Instance#HasTag)
- [`Instance:RemoveTag`](https://create.roblox.com/docs/reference/engine/classes/Instance#RemoveTag)
- Implemented the second argument of the `FindFirstChild` / `FindFirstChildOfClass` / `FindFirstChildWhichIsA` instance methods.
### Changed
- Update to Luau version `0.579`
- Both `stdio.write` and `stdio.ewrite` now support writing arbitrary bytes, instead of only valid UTF-8.
### Fixed
- Fixed `stdio.write` and `stdio.ewrite` not being flushed and causing output to be interleaved. ([#47])
- Fixed `typeof` returning `userdata` for roblox types such as `Instance`, `Vector3`, ...
[#47]: https://github.com/lune-org/lune/pull/47
## `0.6.7` - May 14th, 2023
### Added
- Replaced all of the separate typedef & documentation generation commands with a unified `lune --setup` command.
This command will generate type definition files for all of the builtins and will work with the new `require("@lune/...")` syntax. Note that this also means that there is no longer any way to generate type definitions for globals - this is because they will be removed in the next major release in favor of the beforementioned syntax.
- New releases now include prebuilt binaries for arm64 / aarch64! <br />
These new binaries will have names with the following format:
- `lune-windows-0.6.7-aarch64.exe`
- `lune-linux-0.6.7-aarch64`
- `lune-macos-0.6.7-aarch64`
- Added global types to documentation site
## `0.6.6` - April 30th, 2023
### Added
- Added tracing / logging for rare and hard to diagnose error cases, which can be configured using the env var `RUST_LOG`.
### Changed
- The `_VERSION` global now follows a consistent format `Lune x.y.z+luau` to allow libraries to check against it for version requirements.
Examples:
- `Lune 0.0.0+0`
- `Lune 1.0.0+500`
- `Lune 0.11.22+9999`
- Updated to Luau version `0.573`
- Updated `rbx-dom` to support reading and writing `Font` datatypes
### Fixed
- Fixed `_G` not being a readable & writable table
- Fixed `_G` containing normal globals such as `print`, `math`, ...
- Fixed using instances as keys in tables
## `0.6.5` - March 27th, 2023
### Changed
- Functions such as `print`, `warn`, ... now respect `__tostring` metamethods.
### Fixed
- Fixed access of roblox instance properties such as `Workspace.Terrain`, `game.Workspace` that are actually links to child instances. <br />
These properties are always guaranteed to exist, and they are not always properly set, meaning they must be found through an internal lookup.
- Fixed issues with the `CFrame.lookAt` and `CFrame.new(Vector3, Vector3)` constructors.
- Fixed issues with CFrame math operations returning rotation angles in the wrong order.
## `0.6.4` - March 26th, 2023
### Fixed
- Fixed instances with attributes not saving if they contain integer attributes.
- Fixed attributes not being set properly if the instance has an empty attributes property.
- Fixed error messages for reading & writing roblox files not containing the full error message.
- Fixed crash when trying to access an instance reference property that points to a destroyed instance.
- Fixed crash when trying to save instances that contain unsupported attribute types.
## `0.6.3` - March 26th, 2023
### Added
- Added support for instance tags & `CollectionService` in the `roblox` built-in. <br />
Currently implemented methods are listed on the [docs site](https://lune-org.github.io/docs/roblox/4-api-status).
### Fixed
- Fixed accessing a destroyed instance printing an error message even if placed inside a pcall.
- Fixed cloned instances not having correct instance reference properties set (`ObjectValue.Value`, `Motor6D.Part0`, ...)
- Fixed `Instance::GetDescendants` returning the same thing as `Instance::GetChildren`.
## `0.6.2` - March 25th, 2023
This release adds some new features and fixes for the `roblox` built-in.
### Added
- Added `GetAttribute`, `GetAttributes` and `SetAttribute` methods for instances.
- Added support for getting & setting properties that are instance references.
### Changed
- Improved handling of optional property types such as optional cframes & default physical properties.
### Fixed
- Fixed handling of instance properties that are serialized as binary strings.
## `0.6.1` - March 22nd, 2023
### Fixed
- Fixed `writePlaceFile` and `writeModelFile` in the new `roblox` built-in making mysterious "ROOT" instances.
## `0.6.0` - March 22nd, 2023
### Added
- Added a `roblox` built-in
If you're familiar with [Remodel](https://github.com/rojo-rbx/remodel), this new built-in contains more or less the same APIs, integrated into Lune. <br />
There are just too many new APIs to list in this changelog, so head over to the [docs sit](https://lune-org.github.io/docs/roblox/1-introduction) to learn more!
- Added a `serde` built-in
This built-in contains previously available functions `encode` and `decode` from the `net` global. <br />
The plan is for this built-in to contain more serialization and encoding functionality in the future.
- `require` has been reimplemented and overhauled in several ways:
- New built-ins such as `roblox` and `serde` can **_only_** be imported using `require("@lune/roblox")`, `require("@lune/serde")`, ...
- Previous globals such as `fs`, `net` and others can now _also_ be imported using `require("@lune/fs")`, `require("@lune/net")`, ...
- Requiring a script is now completely asynchronous and will not block lua threads other than the caller.
- Requiring a script will no longer error when using async APIs in the main body of the required script.
All new built-ins will be added using this syntax and new built-ins will no longer be available in the global scope, and current globals will stay available as globals until proper editor and LSP support is available to ensure Lune users have a good development experience. This is the first step towards moving away from adding each library as a global, and allowing Lune to have more built-in libraries in general.
Behavior otherwise stays the same, and requires are still relative to file unless the special `@` prefix is used.
- Added `net.urlEncode` and `net.urlDecode` for URL-encoding and decoding strings
### Changed
- Renamed the global `info` function to `printinfo` to make it less ambiguous
### Removed
- Removed experimental `net.encode` and `net.decode` functions, since they are now available using `require("@lune/serde")`
- Removed option to preserve default Luau require behavior
## `0.5.6` - March 11th, 2023
### Added
- Added support for shebangs at the top of a script, meaning scripts such as this one will now run without throwing a syntax error:
```lua
#!/usr/bin/env lune
print("Hello, world!")
```
### Fixed
- Fixed `fs.writeFile` and `fs.readFile` not working with strings / files that are invalid utf-8
## `0.5.5` - March 8th, 2023
### Added
- Added support for running scripts by passing absolute file paths in the CLI
- This does not have the restriction of scripts having to use the `.luau` or `.lua` extension, since it is presumed that if you pass an absolute path you know exactly what you are doing
### Changed
- Improved error messages for passing invalid file names / file paths substantially - they now include helpful formatting to make file names distinct from file extensions, and give suggestions on how to solve the problem
- Improved general formatting of error messages, both in the CLI and for Luau scripts being run
### Fixed
- Fixed the CLI being a bit too picky about file names when trying to run files in `lune` or `.lune` directories
- Fixed documentation misses from large changes made in version `0.5.0`
## `0.5.4` - March 7th, 2023
### Added
- Added support for reading scripts from stdin by passing `"-"` as the script name
- Added support for close codes in the `net` WebSocket APIs:
- A close code can be sent by passing it to `socket.close`
- A received close code can be checked with the `socket.closeCode` value, which is populated after a socket has been closed - note that using `socket.close` will not set the close code value, it is only set when received and is guaranteed to exist after closure
### Changed
- Update to Luau version 0.566
### Fixed
- Fixed scripts having to be valid utf8, they may now use any kind of encoding that base Luau supports
- The `net` WebSocket APIs will no longer return `nil` for partial messages being received in `socket.next`, and will instead wait for the full message to arrive
## `0.5.3` - February 26th, 2023
### Fixed
- Fixed `lune --generate-selene-types` generating an invalid Selene definitions file
- Fixed type definition parsing issues on Windows
## `0.5.2` - February 26th, 2023
### Fixed
- Fixed crash when using `stdio.color()` or `stdio.style()` in a CI environment or non-interactive terminal
## `0.5.1` - February 25th, 2023
### Added
- Added `net.encode` and `net.decode` which are equivalent to `net.jsonEncode` and `net.jsonDecode`, but with support for more formats.
**_WARNING: Unstable API_**
_This API is unstable and may change or be removed in the next major version of Lune. The purpose of making a new release with these functions is to gather feedback from the community, and potentially replace the JSON-specific encoding and decoding utilities._
Example usage:
```lua
local toml = net.decode("toml", [[
[package]
name = "my-cool-toml-package"
version = "0.1.0"
[values]
epic = true
]])
assert(toml.package.name == "my-cool-toml-package")
assert(toml.package.version == "0.1.0")
assert(toml.values.epic == true)
```
### Fixed
- Fixed indentation of closing curly bracket when printing tables
## `0.5.0` - February 23rd, 2023
### Added
- Added auto-generated API reference pages and documentation using GitHub wiki pages
- Added support for `query` in `net.request` parameters, which enables usage of query parameters in URLs without having to manually URL encode values.
- Added a new function `fs.move` to move / rename a file or directory from one path to another.
- Implemented a new task scheduler which resolves several long-standing issues:
- Issues with yielding across the C-call/metamethod boundary no longer occur when calling certain async APIs that Lune provides.
- Ordering of interleaved calls to `task.spawn/task.defer` is now completely deterministic, deferring is now guaranteed to run last even in these cases.
- The minimum wait time possible when using `task.wait` and minimum delay time using `task.delay` are now much smaller, and only limited by the underlying OS implementation. For most systems this means `task.wait` and `task.delay` are now accurate down to about 5 milliseconds or less.
### Changed
- Type definitions are now bundled as part of the Lune executable, meaning they no longer need to be downloaded.
- `lune --generate-selene-types` will generate the Selene type definitions file, replacing `lune --download-selene-types`
- `lune --generate-luau-types` will generate the Luau type definitions file, replacing `lune --download-luau-types`
- Improved accuracy of Selene type definitions, strongly typed arrays are now used where possible
- Improved error handling and messages for `net.serve`
- Improved error handling and messages for `stdio.prompt`
- File path representations on Windows now use legacy paths instead of UNC paths wherever possible, preventing some confusing cases where file paths don't work as expected
### Fixed
- Fixed `process.cwd` not having the correct ending path separator on Windows
- Fixed remaining edge cases where the `task` and `coroutine` libraries weren't interoperable
- Fixed `task.delay` keeping the script running even if it was cancelled using `task.cancel`
- Fixed `stdio.prompt` blocking all other lua threads while prompting for input
## `0.4.0` - February 11th, 2023
### Added
- ### Web Sockets
`net` now supports web sockets for both clients and servers! <br />
Note that the web socket object is identical on both client and
server, but how you retrieve a web socket object is different.
#### Server API
The server web socket API is an extension of the existing `net.serve` function. <br />
This allows for serving both normal HTTP requests and web socket requests on the same port.
Example usage:
```lua
net.serve(8080, {
handleRequest = function(request)
return "Hello, world!"
end,
handleWebSocket = function(socket)
task.delay(10, function()
socket.send("Timed out!")
socket.close()
end)
-- The message will be nil when the socket has closed
repeat
local messageFromClient = socket.next()
if messageFromClient == "Ping" then
socket.send("Pong")
end
until messageFromClient == nil
end,
})
```
#### Client API
Example usage:
```lua
local socket = net.socket("ws://localhost:8080")
socket.send("Ping")
task.delay(5, function()
socket.close()
end)
-- The message will be nil when the socket has closed
repeat
local messageFromServer = socket.next()
if messageFromServer == "Ping" then
socket.send("Pong")
end
until messageFromServer == nil
```
### Changed
- `net.serve` now returns a `NetServeHandle` which can be used to stop serving requests safely.
Example usage:
```lua
local handle = net.serve(8080, function()
return "Hello, world!"
end)
print("Shutting down after 1 second...")
task.wait(1)
handle.stop()
print("Shut down succesfully")
```
- The third and optional argument of `process.spawn` is now a global type `ProcessSpawnOptions`.
- Setting `cwd` in the options for `process.spawn` to a path starting with a tilde (`~`) will now use a path relative to the platform-specific home / user directory.
- `NetRequest` query parameters value has been changed to be a table of key-value pairs similar to `process.env`.
If any query parameter is specified more than once in the request url, the value chosen will be the last one that was specified.
- The internal http client for `net.request` now reuses headers and connections for more efficient requests.
- Refactored the Lune rust crate to be much more user-friendly and documented all of the public functions.
### Fixed
- Fixed `process.spawn` blocking all lua threads if the spawned child process yields.
## `0.3.0` - February 6th, 2023
### Added
- Added a new global `stdio` which replaces `console`
- Added `stdio.write` which writes a string directly to stdout, without any newlines
- Added `stdio.ewrite` which writes a string directly to stderr, without any newlines
- Added `stdio.prompt` which will prompt the user for different kinds of input
Example usage:
```lua
local text = stdio.prompt()
local text2 = stdio.prompt("text", "Please write some text")
local didConfirm = stdio.prompt("confirm", "Please confirm this action")
local optionIndex = stdio.prompt("select", "Please select an option", { "one", "two", "three" })
local optionIndices = stdio.prompt(
"multiselect",
"Please select one or more options",
{ "one", "two", "three", "four", "five" }
)
```
### 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.
### Removed
- 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
### Added
- Added global types for networking & child process APIs
- `net.request` gets `NetFetchParams` and `NetFetchResponse` for its argument and return value
- `net.serve` gets `NetRequest` and `NetResponse` for the handler function argument and return value
- `process.spawn` gets `ProcessSpawnOptions` for its third and optional parameter
### Changed
- Reorganize repository structure to take advantage of cargo workspaces, improves compile times
## `0.2.1` - February 3rd, 2023
### Added
- Added support for string interpolation syntax (update to Luau 0.561)
- Added network server functionality using `net.serve`
Example usage:
```lua
net.serve(8080, function(request)
print(`Got a {request.method} request at {request.path}!`)
local data = net.jsonDecode(request.body)
-- For simple text responses with a 200 status
return "OK"
-- For anything else
return {
status = 203,
headers = { ["Content-Type"] = "application/json" },
body = net.jsonEncode({
message = "echo",
data = data,
})
}
end)
```
### Changed
- Improved type definitions file for Selene, now including constants like `process.env` + tags such as `readonly` and `mustuse` wherever applicable
### Fixed
- Fixed type definitions file for Selene not including all API members and parameters
- Fixed `process.exit` exiting at the first yield instead of exiting instantly as it should
## `0.2.0` - January 28th, 2023
### Added
- Added full documentation for all global APIs provided by Lune! This includes over 200 lines of pure documentation about behavior & error cases for all of the current 35 constants & functions. Check the [README](/README.md) to find out how to enable documentation in your editor.
- Added a third argument `options` for `process.spawn`:
- `cwd` - The current working directory for the process
- `env` - Extra environment variables to give to the process
- `shell` - Whether to run in a shell or not - set to `true` to run using the default shell, or a string to run using a specific shell
- `stdio` - How to treat output and error streams from the child process - set to `"inherit"` to pass output and error streams to the current process
- Added `process.cwd`, the path to the current working directory in which the Lune script is running
## `0.1.3` - January 25th, 2023
### Added
- Added a `--list` subcommand to list scripts found in the `lune` or `.lune` directory.
## `0.1.2` - January 24th, 2023
### Added
- Added automatic publishing of the Lune library to [crates.io](https://crates.io/crates/lune)
### Fixed
- Fixed scripts that terminate instantly sometimes hanging
## `0.1.1` - January 24th, 2023
### Fixed
- Fixed errors containing `./` and / or `../` in the middle of file paths
- Potential fix for spawned processes that yield erroring with "attempt to yield across metamethod/c-call boundary"
## `0.1.0` - January 24th, 2023
### Added
- `task` now supports passing arguments in `task.spawn` / `task.delay` / `task.defer`
- `require` now uses paths relative to the file instead of being relative to the current directory, which is consistent with almost all other languages but not original Lua / Luau - this is a breaking change but will allow for proper packaging of third-party modules and more in the future.
- **_NOTE:_** _If you still want to use the default Lua behavior instead of relative paths, set the environment variable `LUAU_PWD_REQUIRE` to `true`_
### Changed
- Improved error message when an invalid file path is passed to `require`
- Much improved error formatting and stack traces
### Fixed
- Fixed downloading of type definitions making json files instead of the proper format
- Process termination will now always make sure all lua state is cleaned up before exiting, in all cases
## `0.0.6` - January 23rd, 2023
### Added
- Initial implementation of [Roblox's task library](https://create.roblox.com/docs/reference/engine/libraries/task), with some caveats:
- Minimum wait / delay time is currently set to 10ms, subject to change
- It is not yet possible to pass arguments to tasks created using `task.spawn` / `task.delay` / `task.defer`
- Timings for `task.defer` are flaky and deferred tasks are not (yet) guaranteed to run after spawned tasks
With all that said, everything else should be stable!
- Mixing and matching the `coroutine` library with `task` works in all cases
- `process.exit()` will stop all spawned / delayed / deferred threads and exit the process
- Lune is guaranteed to keep running until there are no longer any waiting threads
If any of the abovementioned things do not work as expected, it is a bug, please file an issue!
### Fixed
- Potential fix for spawned processes that yield erroring with "attempt to yield across metamethod/c-call boundary"
## `0.0.5` - January 22nd, 2023
### Added
- Added full test suites for all Lune globals to ensure correct behavior
- Added library version of Lune that can be used from other Rust projects
### Changed
- Large internal changes to allow for implementing the `task` library.
- Improved general formatting of errors to make them more readable & glanceable
- Improved output formatting of non-primitive types
- Improved output formatting of empty tables
### Fixed
- Fixed double stack trace for certain kinds of errors
## `0.0.4` - January 21st, 2023
### Added
- Added `process.args` for inspecting values given to Lune when running (read only)
- Added `process.env` which is a plain table where you can get & set environment variables
### Changed
- Improved error formatting & added proper file name to stack traces
### Removed
- Removed `...` for process arguments, use `process.args` instead
- Removed individual functions for getting & setting environment variables, use `process.env` instead
## `0.0.3` - January 20th, 2023
### Added
- Added networking functions under `net`
Example usage:
```lua
local apiResult = net.request({
url = "https://jsonplaceholder.typicode.com/posts/1",
method = "PATCH",
headers = {
["Content-Type"] = "application/json",
},
body = net.jsonEncode({
title = "foo",
body = "bar",
}),
})
local apiResponse = net.jsonDecode(apiResult.body)
assert(apiResponse.title == "foo", "Invalid json response")
assert(apiResponse.body == "bar", "Invalid json response")
```
- Added console logging & coloring functions under `console`
This piece of code:
```lua
local tab = { Integer = 1234, Hello = { "World" } }
console.log(tab)
```
Will print the following formatted text to the console, **_with syntax highlighting_**:
```lua
{
Integer = 1234,
Hello = {
"World",
}
}
```
Additional utility functions exist with the same behavior but that also print out a colored
tag together with any data given to them: `console.info`, `console.warn`, `console.error` -
These print out prefix tags `[INFO]`, `[WARN]`, `[ERROR]` in blue, orange, and red, respectively.
### Changed
- The `json` api is now part of `net`
- `json.encode` becomes `net.jsonEncode`
- `json.decode` become `net.jsonDecode`
### Fixed
- Fixed JSON decode not working properly
## `0.0.2` - January 19th, 2023
### Added
- Added support for command-line parameters to scripts
These can be accessed as a vararg in the root of a script:
```lua
local firstArg: string, secondArg: string = ...
print(firstArg, secondArg)
```
- Added CLI parameters for downloading type definitions:
- `lune --download-selene-types` to download Selene types to the current directory
- `lune --download-luau-types` to download Luau types to the current directory
These files will be downloaded as `lune.yml` and `luneTypes.d.luau`
respectively and are also available in each release on GitHub.
## `0.0.1` - January 18th, 2023
Initial Release
================================================
FILE: CONTRIBUTING.md
================================================
<!-- markdownlint-disable MD001 -->
<!-- markdownlint-disable MD033 -->
# Contributing
---
### Reporting a Bug
- Make sure the bug has not already been reported by searching on GitHub under [Issues](https://github.com/lune-org/lune/issues).
- If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/lune-org/lune/issues/new). Be sure to include a **title and description**, as much relevant information as possible, and if applicable, a **code sample** or a **test case** demonstrating the expected behavior.
---
### Contributing - Bug Fixes
1. Make sure an [issue](https://github.com/lune-org/lune/issues) has been created for the bug first, so that it can be tracked and searched for in the repository history. This is not mandatory for small fixes.
2. Open a new GitHub pull request for it. A pull request for a bug fix must include:
- A clear and concise description of the bug it is fixing.
- A new test file ensuring there are no regressions after the bug has been fixed.
- A link to the relevant issue, or a `Fixes #issue` line, if an issue exists.
### Contributing - Features
1. Make sure an [issue](https://github.com/lune-org/lune/issues) has been created for the feature first, so that it can be tracked and searched for in the repository history. If you are making changes to an existing feature, and no issue exists, one should be created for the proposed changes.
2. Any API design or considerations should first be brought up and discussed in the relevant issue, to prevent long review times on pull requests and unnecessary work for maintainers.
3. Familiarize yourself with the codebase and the tools you will be using. Some important parts include:
- The [mlua](https://crates.io/crates/mlua) library, which we use to interface with Luau.
- Any [built-in libraries](https://github.com/lune-org/lune/tree/main/src/lune/builtins) that are relevant for your new feature. If you are making a new built-in library, refer to existing ones for structure and implementation details.
- Our toolchain, notably [StyLua](https://github.com/JohnnyMorganz/StyLua), [rustfmt](https://github.com/rust-lang/rustfmt), and [clippy](https://github.com/rust-lang/rust-clippy). If you do not use these tools there is a decent chance CI will fail on your pull request, blocking it from getting approved.
4. Write some code!
5. Open a new GitHub pull request. A pull request for a feature must include:
- A clear and concise description of the new feature or changes to the feature.
- Test files for any added or changed functionality.
- A link to the relevant issue, or a `Closes #issue` line.
### Contributing - Formatting & Cosmetic Changes
Changes that are purely cosmetic, and do not add to the stability, functionality, or testability of Lune, will generally not be accepted unless there has been previous discussion about the changes being made.
### Contributing - Documentation
#### Documentation Site
Check out the [docs](https://github.com/lune-org/docs) repository and its contribution guidelines.
#### Type Definitions
If type definitions for built-in libraries need improvements:
1. Check out the [types](https://github.com/lune-org/lune/tree/main/types) directory at the root of the repository.
2. Make the desired changes, and verify that they have the desired outcome.
3. Open a new GitHub pull request for your changes.
---
### Publishing a Release
The Lune release process is semi-automated, and takes care of most things for you. Here's how to create a new release:
1. Make sure the changelog is up to date and contains all of the changes since the last release.
2. Add the release date in the changelog + set a new version number in `Cargo.toml`.
3. Commit and push changes from step 2 to GitHub. This will automatically publish the Lune library to [crates.io](https://crates.io) when the version number changes.
4. Trigger the [release](https://github.com/lune-org/lune/actions/workflows/release.yaml) workflow on GitHub manually, and wait for it to finish. Find the new pending release in the [Releases](https://github.com/lune-org/lune/releases) section.
5. Add in changes from the changelog for the new pending release into the description, hit "accept" on creating a new version tag, and publish 🚀
---
If you have any questions, check out the `#lune` channel in the [Roblox OSS discord](https://discord.gg/H9WqmFAB5Y), where most of our realtime discussion takes place!
Thank you for contributing to Lune! 🌙
================================================
FILE: Cargo.toml
================================================
[workspace]
resolver = "2"
default-members = ["crates/lune"]
members = [
"crates/lune",
"crates/lune-roblox",
"crates/lune-std",
"crates/lune-std-datetime",
"crates/lune-std-fs",
"crates/lune-std-luau",
"crates/lune-std-net",
"crates/lune-std-process",
"crates/lune-std-regex",
"crates/lune-std-roblox",
"crates/lune-std-serde",
"crates/lune-std-stdio",
"crates/lune-std-task",
"crates/lune-utils",
"crates/mlua-luau-scheduler",
]
# Profile for building the release binary, with the following options set:
#
# 1. Optimize for size
# 2. Automatically strip symbols from the binary
# 3. Enable link-time optimization
#
# Note that we could abort instead of panicking to cut down on size
# even more, but because we use the filesystem & some other APIs we
# need the panic unwinding to properly handle usage of said APIs
#
[profile.release]
opt-level = "z"
strip = true
lto = true
# Lints for all crates in the workspace
#
# 1. Error on all lints by default, then make cargo + clippy pedantic lints just warn
# 2. Selectively allow some lints that are _too_ pedantic, such as:
# - Casts between number types
# - Module naming conventions
# - Imports and multiple dependency versions
[workspace.lints.clippy]
all = { level = "deny", priority = -3 }
cargo = { level = "warn", priority = -2 }
pedantic = { level = "warn", priority = -1 }
cast_lossless = { level = "allow", priority = 1 }
cast_possible_truncation = { level = "allow", priority = 1 }
cast_possible_wrap = { level = "allow", priority = 1 }
cast_precision_loss = { level = "allow", priority = 1 }
cast_sign_loss = { level = "allow", priority = 1 }
similar_names = { level = "allow", priority = 1 }
unnecessary_wraps = { level = "allow", priority = 1 }
unnested_or_patterns = { level = "allow", priority = 1 }
unreadable_literal = { level = "allow", priority = 1 }
multiple_crate_versions = { level = "allow", priority = 1 }
module_inception = { level = "allow", priority = 1 }
module_name_repetitions = { level = "allow", priority = 1 }
needless_pass_by_value = { level = "allow", priority = 1 }
wildcard_imports = { level = "allow", priority = 1 }
================================================
FILE: LICENSE.txt
================================================
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.
================================================
FILE: README.md
================================================
<!-- markdownlint-disable MD033 -->
<!-- markdownlint-disable MD041 -->
<img align="right" width="250" src="assets/logo/tilt_svg.svg" alt="Lune logo" />
<h1 align="center">Lune</h1>
<div align="center">
<div>
<a href="https://crates.io/crates/lune">
<img src="https://img.shields.io/crates/v/lune.svg?label=Version" alt="Current Lune library version" />
</a>
<a href="https://github.com/lune-org/lune/actions">
<img src="https://shields.io/endpoint?url=https://badges.readysetplay.io/workflow/lune-org/lune/ci.yaml" alt="CI status" />
</a>
<a href="https://github.com/lune-org/lune/actions">
<img src="https://shields.io/endpoint?url=https://badges.readysetplay.io/workflow/lune-org/lune/release.yaml" alt="Release status" />
</a>
<a href="https://github.com/lune-org/lune/blob/main/LICENSE.txt">
<img src="https://img.shields.io/github/license/lune-org/lune.svg?label=License&color=informational" alt="Lune license" />
</a>
</div>
</div>
<br/>
A standalone [Luau](https://luau-lang.org) runtime.
Write and run programs, similar to runtimes for other languages such as [Node](https://nodejs.org), [Deno](https://deno.land), [Bun](https://bun.sh), or [Luvit](https://luvit.io) for vanilla Lua.
Lune provides fully asynchronous APIs wherever possible, and is built in Rust 🦀 for speed, safety and correctness.
## Features
- 🌙 Strictly minimal but powerful interface that is easy to read and remember, just like Luau itself
- 🧰 Fully featured APIs for the filesystem, networking, stdio, all included in the small (~5mb zipped) executable
- 📚 World-class documentation, on the web _or_ directly in your editor, no network connection necessary
- 🏡 Familiar runtime environment for Roblox developers, with an included 1-to-1 task scheduler port
- ✏️ Optional built-in library for manipulating Roblox place & model files, and their instances
## Non-goals
- Making programs short and terse - proper autocomplete / intellisense make using Lune just as quick, and readability is important
- Running full Roblox games outside of Roblox - there is some compatibility, but Lune is meant for different purposes
## Where do I start?
Head over to the [Installation](https://lune-org.github.io/docs/getting-started/1-installation) page to get started using Lune!
================================================
FILE: crates/lune/Cargo.toml
================================================
[package]
name = "lune"
version = "0.10.4"
edition = "2024"
license = "MPL-2.0"
repository = "https://github.com/lune-org/lune"
description = "A standalone Luau runtime"
readme = "../../README.md"
keywords = ["cli", "lua", "luau", "runtime"]
categories = ["command-line-interface"]
[[bin]]
name = "lune"
path = "src/main.rs"
[lib]
name = "lune"
path = "src/lib.rs"
[features]
default = ["std", "cli"]
std-datetime = ["dep:lune-std", "lune-std/datetime"]
std-fs = ["dep:lune-std", "lune-std/fs"]
std-luau = ["dep:lune-std", "lune-std/luau"]
std-net = ["dep:lune-std", "lune-std/net"]
std-process = ["dep:lune-std", "lune-std/process"]
std-regex = ["dep:lune-std", "lune-std/regex"]
std-roblox = ["dep:lune-std", "lune-std/roblox"]
std-serde = ["dep:lune-std", "lune-std/serde"]
std-stdio = ["dep:lune-std", "lune-std/stdio"]
std-task = ["dep:lune-std", "lune-std/task"]
std = [
"std-datetime",
"std-fs",
"std-luau",
"std-net",
"std-process",
"std-regex",
"std-roblox",
"std-serde",
"std-stdio",
"std-task",
]
cli = ["dep:clap", "dep:rustyline", "dep:zip", "dep:lune-std-net"]
[lints]
workspace = true
[dependencies]
mlua = { version = "0.11.4", features = ["luau"] }
mlua-luau-scheduler = { version = "0.2.3", path = "../mlua-luau-scheduler" }
anyhow = "1.0"
console = "0.16"
dialoguer = "0.12"
directories = "6.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "2.0"
async-io = "2.4"
async-fs = "2.1"
blocking = "1.6"
futures-lite = "2.6"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
lune-std = { optional = true, version = "0.3.4", path = "../lune-std" }
lune-std-net = { optional = true, version = "0.3.4", path = "../lune-std-net" }
lune-utils = { version = "0.3.4", path = "../lune-utils" }
### CLI
clap = { optional = true, version = "4.1", features = ["derive"] }
rustyline = { optional = true, version = "17.0" }
zip = { optional = true, version = "5.1", default-features = false, features = [
"bzip2",
"deflate",
"deflate64",
"zstd"
] }
================================================
FILE: crates/lune/src/cli/build/base_exe.rs
================================================
use std::{
io::{Cursor, Read},
path::PathBuf,
};
use async_fs as fs;
use blocking::unblock;
use crate::standalone::metadata::CURRENT_EXE;
use super::{
files::write_executable_file_to,
result::{BuildError, BuildResult},
target::{BuildTarget, CACHE_DIR},
};
const RELEASE_REQUEST_HEADERS: &[(&str, &str)] = &[
(
"User-Agent",
concat!(
"Lune/",
env!("CARGO_PKG_VERSION"),
" (",
env!("CARGO_PKG_REPOSITORY"),
")"
),
),
("Accept", "application/octet-stream"),
// ("Accept-Encoding", "gzip"),
];
/**
Discovers the path to the base executable to use for cross-compilation.
If the target is the same as the current system, the current executable is used.
If no binary exists at the target path, it will attempt to download it from the internet.
*/
pub async fn get_or_download_base_executable(target: BuildTarget) -> BuildResult<PathBuf> {
if target.is_current_system() {
return Ok(CURRENT_EXE.to_path_buf());
}
if target.cache_path().exists() {
return Ok(target.cache_path());
}
// The target is not cached, we must download it
println!("Requested target '{target}' does not exist in cache");
let version = env!("CARGO_PKG_VERSION");
let target_triple = format!("lune-{version}-{target}");
let release_url = format!(
"{base_url}/v{version}/{target_triple}.zip",
base_url = "https://github.com/lune-org/lune/releases/download",
);
// NOTE: This is not entirely accurate, but it is clearer for a user
println!("Downloading {target_triple}{}...", target.exe_suffix());
// Try to request to download the zip file from the target url,
// making sure transient errors are handled gracefully and
// with a different error message than "not found"
let url = release_url.parse().expect("release url is valid");
let headers = RELEASE_REQUEST_HEADERS
.iter()
.map(|(k, v)| ((*k).to_string(), (*v).to_string()))
.collect();
let res = lune_std_net::fetch(url, None, Some(headers), None)
.await
.map_err(BuildError::Download)?;
let (parts, body) = res.into_inner().into_parts();
if !parts.status.is_success() {
if parts.status.as_u16() == 404 {
return Err(BuildError::ReleaseTargetNotFound(target));
}
let body = body.into_bytes();
return Err(BuildError::Download(format!(
"Request was not successful\
\nStatus: {}\
\nBody: {}",
parts.status,
if body.len() > 128 {
String::from_utf8_lossy(&body[0..128])
} else {
String::from_utf8_lossy(&body)
}
)));
}
// Start reading the zip file
let zip_file = Cursor::new(body.into_bytes());
// Look for and extract the binary file from the zip file
// NOTE: We use spawn_blocking here since reading a zip
// archive is a somewhat slow / blocking operation
let binary_file_name = format!("lune{}", target.exe_suffix());
let binary_file_handle = unblock(move || {
let mut archive = zip::ZipArchive::new(zip_file)?;
let mut binary = Vec::new();
archive
.by_name(&binary_file_name)
.or(Err(BuildError::ZippedBinaryNotFound(binary_file_name)))?
.read_to_end(&mut binary)?;
Ok::<_, BuildError>(binary)
});
let binary_file_contents = binary_file_handle.await?;
// Finally, write the extracted binary to the cache
if !CACHE_DIR.exists() {
fs::create_dir_all(CACHE_DIR.as_path()).await?;
}
write_executable_file_to(target.cache_path(), binary_file_contents).await?;
println!("Downloaded successfully and added to cache");
Ok(target.cache_path())
}
================================================
FILE: crates/lune/src/cli/build/files.rs
================================================
use std::path::{Path, PathBuf};
use anyhow::Result;
use async_fs as fs;
use futures_lite::prelude::*;
/**
Removes the source file extension from the given path, if it has one.
A source file extension is an extension such as `.lua` or `.luau`.
*/
pub fn remove_source_file_ext(path: &Path) -> PathBuf {
if path
.extension()
.is_some_and(|ext| matches!(ext.to_str(), Some("lua" | "luau")))
{
path.with_extension("")
} else {
path.to_path_buf()
}
}
/**
Writes the given bytes to a file at the specified path,
and makes sure it has permissions to be executed.
*/
pub async fn write_executable_file_to(
path: impl AsRef<Path>,
bytes: impl AsRef<[u8]>,
) -> Result<(), std::io::Error> {
let mut options = fs::OpenOptions::new();
options.write(true).create(true).truncate(true);
#[cfg(unix)]
{
use fs::unix::OpenOptionsExt;
options.mode(0o755); // Read & execute for all, write for owner
}
let mut file = options.open(path).await?;
file.write_all(bytes.as_ref()).await?;
file.flush().await?;
Ok(())
}
================================================
FILE: crates/lune/src/cli/build/mod.rs
================================================
use std::{path::PathBuf, process::ExitCode};
use anyhow::{Context, Result, bail};
use async_fs as fs;
use clap::Parser;
use console::style;
use crate::standalone::metadata::Metadata;
mod base_exe;
mod files;
mod result;
mod target;
use self::base_exe::get_or_download_base_executable;
use self::files::{remove_source_file_ext, write_executable_file_to};
use self::target::BuildTarget;
/// Build a standalone executable
#[derive(Debug, Clone, Parser)]
pub struct BuildCommand {
/// The path to the input file
pub input: PathBuf,
/// The path to the output file - defaults to the
/// input file path with an executable extension
#[clap(short, long)]
pub output: Option<PathBuf>,
/// The target to compile for in the format `os-arch` -
/// defaults to the os and arch of the current system
#[clap(short, long)]
pub target: Option<BuildTarget>,
}
impl BuildCommand {
pub async fn run(self) -> Result<ExitCode> {
// Derive target spec to use, or default to the current host system
let target = self.target.unwrap_or_else(BuildTarget::current_system);
// Derive paths to use, and make sure the output path is
// not the same as the input, so that we don't overwrite it
let output_path = self
.output
.clone()
.unwrap_or_else(|| remove_source_file_ext(&self.input));
let output_path = output_path.with_extension(target.exe_extension());
if output_path == self.input {
if self.output.is_some() {
bail!("output path cannot be the same as input path");
}
bail!(
"output path cannot be the same as input path, please specify a different output path"
);
}
// Try to read the given input file
// FUTURE: We should try and resolve a full require file graph using the input
// path here instead, see the notes in the `standalone` module for more details
let source_code = fs::read(&self.input)
.await
.context("failed to read input file")?;
// Derive the base executable path based on the arguments provided
let base_exe_path = get_or_download_base_executable(target).await?;
// Read the contents of the lune interpreter as our starting point
println!(
"Compiling standalone binary from {}",
style(self.input.display()).green()
);
let patched_bin = Metadata::create_env_patched_bin(base_exe_path, source_code)
.await
.context("failed to create patched binary")?;
// And finally write the patched binary to the output file
println!(
"Writing standalone binary to {}",
style(output_path.display()).blue()
);
write_executable_file_to(output_path, patched_bin).await?; // Read & execute for all, write for owner
Ok(ExitCode::SUCCESS)
}
}
================================================
FILE: crates/lune/src/cli/build/result.rs
================================================
use thiserror::Error;
use super::target::BuildTarget;
/**
Errors that may occur when building a standalone binary
*/
#[derive(Debug, Error)]
pub enum BuildError {
#[error("failed to find lune target '{0}' in GitHub release")]
ReleaseTargetNotFound(BuildTarget),
#[error("failed to find lune binary '{0}' in downloaded zip file")]
ZippedBinaryNotFound(String),
#[error("failed to download lune binary: {0}")]
Download(String),
#[error("failed to unzip lune binary: {0}")]
Unzip(#[from] zip::result::ZipError),
#[error("io error: {0}")]
IoError(#[from] std::io::Error),
}
pub type BuildResult<T, E = BuildError> = std::result::Result<T, E>;
================================================
FILE: crates/lune/src/cli/build/target.rs
================================================
use std::{env::consts::ARCH, fmt, path::PathBuf, str::FromStr, sync::LazyLock};
use directories::BaseDirs;
static HOME_DIR: LazyLock<PathBuf> = LazyLock::new(|| {
BaseDirs::new()
.expect("could not find home directory")
.home_dir()
.to_path_buf()
});
pub static CACHE_DIR: LazyLock<PathBuf> = LazyLock::new(|| HOME_DIR.join(".lune").join("target"));
/**
A target operating system supported by Lune
*/
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BuildTargetOS {
Windows,
Linux,
MacOS,
}
impl BuildTargetOS {
fn current_system() -> Self {
match std::env::consts::OS {
"windows" => Self::Windows,
"linux" => Self::Linux,
"macos" => Self::MacOS,
_ => panic!("unsupported target OS"),
}
}
fn exe_extension(self) -> &'static str {
// NOTE: We can't use the constants from std since
// they are only accessible for the current target
match self {
Self::Windows => "exe",
_ => "",
}
}
fn exe_suffix(self) -> &'static str {
match self {
Self::Windows => ".exe",
_ => "",
}
}
}
impl fmt::Display for BuildTargetOS {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Windows => write!(f, "windows"),
Self::Linux => write!(f, "linux"),
Self::MacOS => write!(f, "macos"),
}
}
}
impl FromStr for BuildTargetOS {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.trim().to_ascii_lowercase().as_str() {
"win" | "windows" => Ok(Self::Windows),
"linux" => Ok(Self::Linux),
"mac" | "macos" | "darwin" => Ok(Self::MacOS),
_ => Err("invalid target OS"),
}
}
}
/**
A target architecture supported by Lune
*/
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BuildTargetArch {
X86_64,
Aarch64,
}
impl BuildTargetArch {
fn current_system() -> Self {
match ARCH {
"x86_64" => Self::X86_64,
"aarch64" => Self::Aarch64,
_ => panic!("unsupported target architecture"),
}
}
}
impl fmt::Display for BuildTargetArch {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::X86_64 => write!(f, "x86_64"),
Self::Aarch64 => write!(f, "aarch64"),
}
}
}
impl FromStr for BuildTargetArch {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.trim().to_ascii_lowercase().as_str() {
"x86_64" | "x64" => Ok(Self::X86_64),
"aarch64" | "arm64" => Ok(Self::Aarch64),
_ => Err("invalid target architecture"),
}
}
}
/**
A full target description that Lune supports (OS + Arch)
This is used to determine the target to build for standalone binaries,
and to download the correct base executable for cross-compilation.
The target may be parsed from and displayed in the form `os-arch`.
Examples of valid targets are:
- `linux-aarch64`
- `linux-x86_64`
- `macos-aarch64`
- `macos-x86_64`
- `windows-x86_64`
*/
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BuildTarget {
pub os: BuildTargetOS,
pub arch: BuildTargetArch,
}
impl BuildTarget {
pub fn current_system() -> Self {
Self {
os: BuildTargetOS::current_system(),
arch: BuildTargetArch::current_system(),
}
}
pub fn is_current_system(&self) -> bool {
self.os == BuildTargetOS::current_system() && self.arch == BuildTargetArch::current_system()
}
pub fn exe_extension(&self) -> &'static str {
self.os.exe_extension()
}
pub fn exe_suffix(&self) -> &'static str {
self.os.exe_suffix()
}
pub fn cache_path(&self) -> PathBuf {
CACHE_DIR.join(format!("{self}{}", self.os.exe_extension()))
}
}
impl fmt::Display for BuildTarget {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}-{}", self.os, self.arch)
}
}
impl FromStr for BuildTarget {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let (left, right) = s
.split_once('-')
.ok_or("target must be in the form `os-arch`")?;
let os = left.parse()?;
let arch = right.parse()?;
Ok(Self { os, arch })
}
}
================================================
FILE: crates/lune/src/cli/list.rs
================================================
use std::{fmt::Write as _, process::ExitCode};
use anyhow::Result;
use clap::Parser;
use super::utils::listing::{find_lune_scripts, sort_lune_scripts, write_lune_scripts_list};
/// List scripts available to run
#[derive(Debug, Clone, Parser)]
pub struct ListCommand {}
impl ListCommand {
pub async fn run(self) -> Result<ExitCode> {
let sorted_relative = find_lune_scripts(false).await.map(sort_lune_scripts);
let sorted_home_dir = find_lune_scripts(true).await.map(sort_lune_scripts);
if sorted_relative.is_err() && sorted_home_dir.is_err() {
eprintln!("{}", sorted_relative.unwrap_err());
return Ok(ExitCode::FAILURE);
}
let sorted_relative = sorted_relative.unwrap_or(Vec::new());
let sorted_home_dir = sorted_home_dir.unwrap_or(Vec::new());
let mut buffer = String::new();
if !sorted_relative.is_empty() {
if sorted_home_dir.is_empty() {
write!(&mut buffer, "Available scripts:")?;
} else {
write!(&mut buffer, "Available scripts in current directory:")?;
}
write_lune_scripts_list(&mut buffer, sorted_relative)?;
}
if !sorted_home_dir.is_empty() {
write!(&mut buffer, "Available global scripts:")?;
write_lune_scripts_list(&mut buffer, sorted_home_dir)?;
}
if buffer.is_empty() {
println!("No scripts found.");
} else {
print!("{buffer}");
}
Ok(ExitCode::SUCCESS)
}
}
================================================
FILE: crates/lune/src/cli/mod.rs
================================================
use std::{env::args_os, process::ExitCode};
use anyhow::Result;
use clap::{Parser, Subcommand};
pub(crate) mod build;
pub(crate) mod list;
pub(crate) mod repl;
pub(crate) mod run;
pub(crate) mod setup;
pub(crate) mod utils;
pub use self::{
build::BuildCommand, list::ListCommand, repl::ReplCommand, run::RunCommand, setup::SetupCommand,
};
#[derive(Debug, Clone, Subcommand)]
pub enum CliSubcommand {
Run(RunCommand),
List(ListCommand),
Setup(SetupCommand),
Build(BuildCommand),
Repl(ReplCommand),
}
impl Default for CliSubcommand {
fn default() -> Self {
Self::Repl(ReplCommand::default())
}
}
/// Lune, a standalone Luau runtime
#[derive(Parser, Debug, Default, Clone)]
#[command(version, about, long_about = None)]
pub struct Cli {
#[clap(subcommand)]
subcommand: Option<CliSubcommand>,
}
impl Cli {
pub fn new() -> Self {
// TODO: Figure out if there is a better way to do this using clap ... ?
// https://github.com/lune-org/lune/issues/253
if args_os()
.nth(1)
.is_some_and(|arg| arg.eq_ignore_ascii_case("run"))
{
let Some(script_path) = args_os()
.nth(2)
.and_then(|arg| arg.to_str().map(String::from))
else {
return Self::parse(); // Will fail and return the help message
};
let script_args = args_os()
.skip(3)
.filter_map(|arg| arg.to_str().map(String::from))
.collect::<Vec<_>>();
Self {
subcommand: Some(CliSubcommand::Run(RunCommand {
script_path,
script_args,
})),
}
} else {
Self::parse()
}
}
pub async fn run(self) -> Result<ExitCode> {
match self.subcommand.unwrap_or_default() {
CliSubcommand::Run(cmd) => cmd.run().await,
CliSubcommand::List(cmd) => cmd.run().await,
CliSubcommand::Setup(cmd) => cmd.run().await,
CliSubcommand::Build(cmd) => cmd.run().await,
CliSubcommand::Repl(cmd) => cmd.run().await,
}
}
}
================================================
FILE: crates/lune/src/cli/repl.rs
================================================
use std::{path::PathBuf, process::ExitCode};
use anyhow::{Context, Result};
use async_fs as fs;
use clap::Parser;
use directories::UserDirs;
use rustyline::{DefaultEditor, error::ReadlineError};
use lune::Runtime;
const MESSAGE_WELCOME: &str = concat!("Lune v", env!("CARGO_PKG_VERSION"));
const MESSAGE_INTERRUPT: &str = "Interrupt: ^C again to exit";
enum PromptState {
Regular,
Continuation,
}
/// Launch an interactive REPL (default)
#[derive(Debug, Clone, Default, Parser)]
pub struct ReplCommand {}
impl ReplCommand {
pub async fn run(self) -> Result<ExitCode> {
println!("{MESSAGE_WELCOME}");
let history_file_path: &PathBuf = &UserDirs::new()
.context("Failed to find user home directory")?
.home_dir()
.join(".lune_history");
if !history_file_path.exists() {
fs::write(history_file_path, &[]).await?;
}
let mut repl = DefaultEditor::new()?;
repl.load_history(history_file_path)?;
let mut interrupt_counter = 0;
let mut prompt_state = PromptState::Regular;
let mut source_code = String::new();
let mut lune_instance = Runtime::new()?;
loop {
let prompt = match prompt_state {
PromptState::Regular => "> ",
PromptState::Continuation => ">> ",
};
match repl.readline(prompt) {
Ok(code) => {
interrupt_counter = 0;
// TODO: Should we add history entries for each separate line?
// Or should we add and save history only when we have complete
// lua input that may or may not be multiple lines long?
repl.add_history_entry(&code)?;
repl.save_history(history_file_path)?;
match prompt_state {
PromptState::Regular => source_code = code,
PromptState::Continuation => source_code.push_str(&code),
}
}
Err(ReadlineError::Eof) => break,
Err(ReadlineError::Interrupted) => {
interrupt_counter += 1;
// NOTE: We actually want the user to do ^C twice to exit,
// and if we get an interrupt we should continue to the next
// readline loop iteration so we don't run input code twice
if interrupt_counter == 1 {
println!("{MESSAGE_INTERRUPT}");
continue;
}
break;
}
Err(err) => {
eprintln!("REPL ERROR: {err}");
return Ok(ExitCode::FAILURE);
}
}
match lune_instance.run_custom("REPL", &source_code).await {
Ok(_) => prompt_state = PromptState::Regular,
Err(err) => {
if err.is_incomplete_input() {
prompt_state = PromptState::Continuation;
source_code.push('\n');
} else {
eprintln!("{err}");
}
}
}
}
repl.save_history(history_file_path)?;
Ok(ExitCode::SUCCESS)
}
}
================================================
FILE: crates/lune/src/cli/run.rs
================================================
use std::{env, io::stdin, process::ExitCode};
use anyhow::{Context, Result};
use blocking::Unblock;
use clap::Parser;
use futures_lite::prelude::*;
use lune::Runtime;
use super::utils::files::discover_script_path_including_lune_dirs;
/// Run a script
#[derive(Debug, Clone, Parser)]
pub struct RunCommand {
/// Script name or full path to the file to run
pub(super) script_path: String,
/// Arguments to pass to the script, stored in process.args
pub(super) script_args: Vec<String>,
}
impl RunCommand {
pub async fn run(self) -> Result<ExitCode> {
// Check if the user has explicitly disabled JIT (on by default)
let jit_disabled = env::var("LUNE_LUAU_JIT")
.ok()
.is_some_and(|s| matches!(s.as_str(), "0" | "false" | "off"));
// Create a new lune runtime with all globals & run the script
let mut rt = Runtime::new()?
.with_args(self.script_args)
.with_jit(!jit_disabled);
// Figure out if we should run stdin or run a file,
// reading from stdin is marked by passing a single "-"
// (dash) as the script name to run to the cli
let result = if &self.script_path == "-" {
let mut stdin_contents = Vec::new();
Unblock::new(stdin())
.read_to_end(&mut stdin_contents)
.await
.context("Failed to read script contents from stdin")?;
rt.run_custom("stdin", stdin_contents).await
} else {
let file_path = discover_script_path_including_lune_dirs(&self.script_path)?;
rt.run_file(file_path).await
};
Ok(match result {
Err(err) => {
eprintln!("{err}");
ExitCode::FAILURE
}
Ok(values) => ExitCode::from(values.status()),
})
}
}
================================================
FILE: crates/lune/src/cli/setup.rs
================================================
use std::{io::ErrorKind, process::ExitCode};
use anyhow::{Context, Result};
use async_fs as fs;
use clap::Parser;
use directories::UserDirs;
use thiserror::Error;
use serde_json::Value as JsonValue;
const LUAURC_PATH: &str = ".luaurc";
/// Set up type definitions for your editor
#[derive(Debug, Clone, Parser)]
pub struct SetupCommand {}
impl SetupCommand {
pub async fn run(self) -> Result<ExitCode> {
generate_typedef_files_from_definitions()
.await
.expect("Failed to generate typedef files");
let mut luaurc = read_or_create_luaurc().await?;
add_values_to_luaurc(&mut luaurc);
write_luaurc(luaurc).await?;
println!(
"Type definitions for Lune v{} have been set up successfully.\
\nYou may need to restart your editor for the changes to take effect.",
lune_version()
);
Ok(ExitCode::SUCCESS)
}
}
#[derive(Debug, Clone, Copy, Error)]
enum SetupError {
#[error("Failed to read settings")]
Read,
#[error("Failed to write settings")]
Write,
#[error("Failed to parse settings")]
Deserialize,
#[error("Failed to create settings")]
Serialize,
}
fn lune_version() -> &'static str {
env!("CARGO_PKG_VERSION")
}
async fn read_or_create_luaurc() -> Result<JsonValue, SetupError> {
match fs::read(LUAURC_PATH).await {
Err(e) if e.kind() == ErrorKind::NotFound => match fs::write(LUAURC_PATH, "{}").await {
Err(_) => Err(SetupError::Write),
Ok(()) => Ok(JsonValue::Object(serde_json::Map::new())),
},
Err(_) => Err(SetupError::Read),
Ok(contents) => match serde_json::from_slice(&contents) {
Err(_) => Err(SetupError::Deserialize),
Ok(json) => Ok(json),
},
}
}
async fn write_luaurc(luaurc: JsonValue) -> Result<(), SetupError> {
match serde_json::to_vec_pretty(&luaurc) {
Err(_) => Err(SetupError::Serialize),
Ok(mut json) => {
json.push(b'\n');
match fs::write(LUAURC_PATH, json).await {
Err(_) => Err(SetupError::Write),
Ok(()) => Ok(()),
}
}
}
}
fn add_values_to_luaurc(luaurc: &mut JsonValue) {
if let JsonValue::Object(luaurc) = luaurc {
let field = String::from("aliases");
let alias = String::from("lune");
let dir = JsonValue::String(format!("~/.lune/.typedefs/{}/", lune_version()));
if let Some(JsonValue::Object(aliases)) = luaurc.get_mut(&field) {
if aliases.contains_key(&alias) {
if aliases.get(&alias).unwrap() != &dir {
aliases.insert(alias, dir);
}
} else {
aliases.insert(alias, dir);
}
} else {
let mut map = serde_json::Map::new();
map.insert(alias, dir);
luaurc.insert(field, JsonValue::Object(map));
}
}
}
async fn generate_typedef_files_from_definitions() -> Result<String> {
let version_string = env!("CARGO_PKG_VERSION");
let mut dirs_to_write = Vec::new();
let mut files_to_write = Vec::new();
// Create the typedefs dir in the users cache dir
let cache_dir = UserDirs::new()
.context("Failed to find user home directory")?
.home_dir()
.join(".lune")
.join(".typedefs")
.join(version_string);
dirs_to_write.push(cache_dir.clone());
// Make typedef files
for builtin in lune_std::LuneStandardLibrary::ALL {
let name = builtin.name().to_lowercase();
let path = cache_dir.join(&name).with_extension("luau");
files_to_write.push((name, path, builtin.typedefs()));
}
// Write all dirs and files
for dir in dirs_to_write {
fs::create_dir_all(dir).await?;
}
for (_name, path, contents) in files_to_write {
fs::write(path, contents).await?;
}
Ok(version_string.to_string())
}
================================================
FILE: crates/lune/src/cli/utils/files.rs
================================================
use std::path::{Path, PathBuf};
use anyhow::{Context, Result, anyhow};
use console::style;
use directories::UserDirs;
use lune_utils::path::{LuauFilePath, LuauModulePath, get_current_dir};
const LUNE_COMMENT_PREFIX: &str = "-->";
/**
Discovers a script file path based on a given module path *or* file path.
See the documentation for [`LuauModulePath`] for more information about
what a module path vs a script path is.
*/
pub fn discover_script_path(path: impl Into<PathBuf>, in_home_dir: bool) -> Result<PathBuf> {
// First, for legacy compatibility, we will strip any lua/luau file extension,
// and if the entire file stem is simply "init", we will get rid of that too
// This lets users pass "dir/init.luau" and have it resolve to simply "dir",
// which is a valid luau module path, while "dir/init.luau" is not
let path = LuauModulePath::strip(path);
// If we got an absolute path, we should not modify it,
// otherwise we should either resolve against home or cwd
let path = if path.is_absolute() {
path
} else if in_home_dir {
UserDirs::new()
.context("Missing home directory")?
.home_dir()
.join(path)
} else {
get_current_dir().join(path)
};
// The rest of the logic should follow Luau module path resolution rules
match LuauModulePath::resolve(&path) {
Err(e) => Err(anyhow!(
"Failed to resolve script at path {} ({})",
style(path.display()).yellow(),
style(format!("{e:?}")).red()
)),
Ok(m) => match m.target() {
LuauFilePath::File(f) => Ok(f.clone()),
LuauFilePath::Directory(_) => Err(anyhow!(
"Failed to resolve script at path {}\
\nThe path is a directory without an init file",
style(path.display()).yellow()
)),
},
}
}
/**
Discovers a script file path based on a given script name, and tries to
find scripts in `lune` and `.lune` folders if one was not directly found.
Note that looking in `lune` and `.lune` folders is automatically
disabled if the given script name is an absolute path.
Behavior is otherwise exactly the same as for `discover_script_file_path`.
*/
pub fn discover_script_path_including_lune_dirs(path: impl AsRef<Path>) -> Result<PathBuf> {
let path: &Path = path.as_ref();
match discover_script_path(path, false) {
Ok(path) => Ok(path),
Err(e) => {
// If we got any absolute path it means the user has also
// told us to not look in any special relative directories
// so we should error right away with the first err message
if path.is_absolute() {
return Err(e);
}
// Otherwise we take a look in relative lune and .lune
// directories + the home directory for the current user
let res = discover_script_path(Path::new("lune").join(path), false)
.or_else(|_| discover_script_path(Path::new(".lune").join(path), false))
.or_else(|_| discover_script_path(Path::new("lune").join(path), true))
.or_else(|_| discover_script_path(Path::new(".lune").join(path), true));
match res {
// NOTE: The first error message is generally more
// descriptive than the ones for the lune subfolders
Err(_) => Err(e),
Ok(path) => Ok(path),
}
}
}
}
pub fn parse_lune_description_from_file(contents: &str) -> Option<String> {
let mut comment_lines = Vec::new();
for line in contents.lines() {
if let Some(stripped) = line.strip_prefix(LUNE_COMMENT_PREFIX) {
comment_lines.push(stripped);
} else {
break;
}
}
if comment_lines.is_empty() {
None
} else {
let shortest_indent = comment_lines.iter().fold(usize::MAX, |acc, line| {
let first_alphanumeric = line.find(char::is_alphanumeric).unwrap();
acc.min(first_alphanumeric)
});
let unindented_lines = comment_lines
.iter()
.map(|line| line[shortest_indent..].to_string())
.collect::<Vec<_>>()
.join(" ");
Some(unindented_lines)
}
}
================================================
FILE: crates/lune/src/cli/utils/listing.rs
================================================
#![allow(clippy::match_same_arms)]
use std::{
cmp::Ordering, ffi::OsStr, fmt::Write as _, io::ErrorKind, path::PathBuf, sync::LazyLock,
};
use anyhow::{Result, bail};
use async_fs as fs;
use console::Style;
use directories::UserDirs;
use futures_lite::prelude::*;
use super::files::{discover_script_path, parse_lune_description_from_file};
pub static COLOR_BLUE: LazyLock<Style> = LazyLock::new(|| Style::new().blue());
pub static STYLE_DIM: LazyLock<Style> = LazyLock::new(|| Style::new().dim());
pub async fn find_lune_scripts(in_home_dir: bool) -> Result<Vec<(String, String)>> {
let base_path = if in_home_dir {
UserDirs::new().unwrap().home_dir().to_path_buf()
} else {
PathBuf::new()
};
let mut lune_dir = fs::read_dir(base_path.join("lune")).await;
if lune_dir.is_err() {
lune_dir = fs::read_dir(base_path.join(".lune")).await;
}
match lune_dir {
Ok(mut dir) => {
let mut files = Vec::new();
while let Some(entry) = dir.try_next().await? {
let meta = entry.metadata().await?;
if meta.is_file() {
let contents = fs::read(entry.path()).await?;
files.push((entry, meta, contents));
} else if meta.is_dir() {
let entry_path_os = entry.path();
let Some(dir_path) = entry_path_os.to_str() else {
bail!("Failed to cast path to string slice.")
};
let Ok(init_file_path) = discover_script_path(dir_path, in_home_dir) else {
continue;
};
let contents = fs::read(init_file_path).await?;
files.push((entry, meta, contents));
}
}
let parsed: Vec<_> = files
.iter()
.filter(|(entry, _, _)| {
let mut is_match = matches!(
entry.path().extension().and_then(OsStr::to_str),
Some("lua" | "luau")
);
// If the entry is not a lua or luau file, and is a directory,
// then we check if it contains a init.lua(u), and if it does,
// we include it in our Vec
if !is_match
&& entry.path().is_dir()
&& (entry.path().join("init.lua").exists()
|| entry.path().join("init.luau").exists())
{
is_match = true;
}
is_match
})
.map(|(entry, _, contents)| {
let contents_str = String::from_utf8_lossy(contents);
let file_path = entry.path().with_extension("");
let file_name = file_path.file_name().unwrap().to_string_lossy();
let description = parse_lune_description_from_file(&contents_str);
(file_name.to_string(), description.unwrap_or_default())
})
.collect();
Ok(parsed)
}
Err(e) if matches!(e.kind(), ErrorKind::NotFound) => {
bail!("No lune directory was found.")
}
Err(e) => {
bail!("Failed to read lune files!\n{e}")
}
}
}
pub fn sort_lune_scripts(scripts: Vec<(String, String)>) -> Vec<(String, String)> {
let mut sorted = scripts;
sorted.sort_by(|left, right| {
// Prefer scripts that have a description
let left_has_desc = !left.1.is_empty();
let right_has_desc = !right.1.is_empty();
if left_has_desc == right_has_desc {
// If both have a description or both
// have no description, we sort by name
left.0.cmp(&right.0)
} else if left_has_desc {
Ordering::Less
} else {
Ordering::Greater
}
});
sorted
}
pub fn write_lune_scripts_list(buffer: &mut String, scripts: Vec<(String, String)>) -> Result<()> {
let longest_file_name_len = scripts
.iter()
.fold(0, |acc, (file_name, _)| acc.max(file_name.len()));
let script_with_description_exists = scripts.iter().any(|(_, desc)| !desc.is_empty());
// Pre-calculate some strings that will be used often
let prefix = format!("{} ", COLOR_BLUE.apply_to('>'));
let separator = format!("{}", STYLE_DIM.apply_to('-'));
// Write the entire output to a buffer, doing this instead of using individual
// writeln! calls will ensure that no output get mixed up in between these lines
if script_with_description_exists {
for (file_name, description) in scripts {
if description.is_empty() {
write!(buffer, "\n{prefix}{file_name}")?;
} else {
let mut lines = description.lines();
let first_line = lines.next().unwrap_or_default();
let file_spacing = " ".repeat(file_name.len());
let line_spacing = " ".repeat(longest_file_name_len - file_name.len());
write!(
buffer,
"\n{prefix}{file_name}{line_spacing} {separator} {}",
COLOR_BLUE.apply_to(first_line)
)?;
for line in lines {
write!(
buffer,
"\n{prefix}{file_spacing}{line_spacing} {}",
COLOR_BLUE.apply_to(line)
)?;
}
}
}
} else {
for (file_name, _) in scripts {
write!(buffer, "\n{prefix}{file_name}")?;
}
}
// Finally, write an ending newline
writeln!(buffer)?;
Ok(())
}
================================================
FILE: crates/lune/src/cli/utils/mod.rs
================================================
pub mod files;
pub mod listing;
================================================
FILE: crates/lune/src/lib.rs
================================================
#![allow(clippy::cargo_common_metadata)]
mod rt;
#[cfg(test)]
mod tests;
pub use crate::rt::{Runtime, RuntimeError, RuntimeResult, RuntimeReturnValues};
================================================
FILE: crates/lune/src/main.rs
================================================
#![allow(clippy::cargo_common_metadata)]
use std::{io::stderr, process::ExitCode};
#[cfg(feature = "cli")]
pub(crate) mod cli;
pub(crate) mod standalone;
use lune_utils::fmt::Label;
fn main() -> ExitCode {
tracing_subscriber::fmt()
.compact()
.with_env_filter(tracing_subscriber::filter::EnvFilter::from_default_env())
.with_target(true)
.with_timer(tracing_subscriber::fmt::time::uptime())
.with_level(true)
.with_writer(stderr)
.init();
async_io::block_on(async {
if let Some(bin) = standalone::check().await {
return standalone::run(bin).await.unwrap();
}
#[cfg(feature = "cli")]
{
match cli::Cli::new().run().await {
Ok(code) => code,
Err(err) => {
eprintln!("{}\n{err:?}", Label::Error);
ExitCode::FAILURE
}
}
}
#[cfg(not(feature = "cli"))]
{
eprintln!("{}\nCLI feature is disabled", Label::Error);
ExitCode::FAILURE
}
})
}
================================================
FILE: crates/lune/src/rt/mod.rs
================================================
mod result;
mod runtime;
pub use self::result::{RuntimeError, RuntimeResult};
pub use self::runtime::{Runtime, RuntimeReturnValues};
================================================
FILE: crates/lune/src/rt/result.rs
================================================
use std::{
error::Error,
fmt::{Debug, Display, Formatter, Result as FmtResult},
};
use mlua::prelude::*;
use lune_utils::fmt::ErrorComponents;
pub type RuntimeResult<T, E = RuntimeError> = Result<T, E>;
/**
An opaque error type for formatted lua errors.
*/
#[derive(Debug, Clone)]
pub struct RuntimeError {
error: LuaError,
disable_colors: bool,
}
impl RuntimeError {
/**
Enables colorization of the error message when formatted using the [`Display`] trait.
Colorization is enabled by default.
*/
#[must_use]
#[doc(hidden)]
pub fn enable_colors(mut self) -> Self {
self.disable_colors = false;
self
}
/**
Disables colorization of the error message when formatted using the [`Display`] trait.
Colorization is enabled by default.
*/
#[must_use]
#[doc(hidden)]
pub fn disable_colors(mut self) -> Self {
self.disable_colors = true;
self
}
/**
Returns `true` if the error can likely be fixed by appending more input to the source code.
See [`mlua::Error::SyntaxError`] for more information.
*/
#[must_use]
pub fn is_incomplete_input(&self) -> bool {
matches!(
self.error,
LuaError::SyntaxError {
incomplete_input: true,
..
}
)
}
}
impl From<LuaError> for RuntimeError {
fn from(value: LuaError) -> Self {
Self {
error: value,
disable_colors: false,
}
}
}
impl From<&LuaError> for RuntimeError {
fn from(value: &LuaError) -> Self {
Self {
error: value.clone(),
disable_colors: false,
}
}
}
impl Display for RuntimeError {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "{}", ErrorComponents::from(self.error.clone()))
}
}
impl Error for RuntimeError {
fn cause(&self) -> Option<&dyn Error> {
Some(&self.error)
}
}
================================================
FILE: crates/lune/src/rt/runtime.rs
================================================
#![allow(clippy::missing_panics_doc)]
use std::{
ffi::OsString,
path::PathBuf,
sync::{
Arc,
atomic::{AtomicBool, Ordering},
},
};
use async_fs as fs;
use lune_utils::{
path::{LuauModulePath, constants::FILE_CHUNK_PREFIX},
process::{ProcessArgs, ProcessEnv, ProcessJitEnablement},
};
use mlua::prelude::*;
use mlua_luau_scheduler::{Functions, Scheduler};
use super::{RuntimeError, RuntimeResult};
/**
Values returned by running a Lune runtime until completion.
*/
#[derive(Debug)]
#[non_exhaustive]
pub struct RuntimeReturnValues {
/// The exit code manually returned from the runtime, if any.
pub code: Option<u8>,
/// Whether any errors were thrown from threads
/// that were not the main thread, or not.
pub errored: bool,
/// The final values returned by the main thread.
pub values: LuaMultiValue,
}
impl RuntimeReturnValues {
/**
Returns the final, combined "status" of the runtime return values.
If no exit code was explicitly set by either the main thread,
or any threads it may have spawned, the status will be either:
- `0` if no threads errored
- `1` if any threads errored
*/
#[must_use]
pub fn status(&self) -> u8 {
self.code.unwrap_or(u8::from(self.errored))
}
/**
Returns whether the run was considered successful, or not.
See [`RuntimeReturnValues::status`] for more information.
*/
#[must_use]
pub fn success(&self) -> bool {
self.status() == 0
}
}
/**
A Lune runtime.
*/
pub struct Runtime {
lua: Lua,
sched: Scheduler,
args: ProcessArgs,
env: ProcessEnv,
jit: ProcessJitEnablement,
}
impl Runtime {
/**
Creates a new Lune runtime, with a new Luau VM.
Injects standard globals and libraries if any of the `std` features are enabled.
# Errors
- If out of memory or other memory-related errors occur
- If any of the standard globals and libraries fail to inject
*/
pub fn new() -> LuaResult<Self> {
let lua = Lua::new();
let sched = Scheduler::new(lua.clone());
let fns = Functions::new(lua.clone()).expect("has scheduler");
// Overwrite some globals that are not compatible with our scheduler
let co = lua.globals().get::<LuaTable>("coroutine")?;
co.set("resume", fns.resume.clone())?;
co.set("wrap", fns.wrap.clone())?;
// Inject all the globals that are enabled
#[cfg(any(
feature = "std-datetime",
feature = "std-fs",
feature = "std-luau",
feature = "std-net",
feature = "std-process",
feature = "std-regex",
feature = "std-roblox",
feature = "std-serde",
feature = "std-stdio",
feature = "std-task",
))]
{
lune_std::set_global_version(&lua, env!("CARGO_PKG_VERSION"));
lune_std::inject_globals(lua.clone())?;
}
// Sandbox the Luau VM and make it go zooooooooom
lua.sandbox(true)?;
// _G table needs to be injected again after sandboxing,
// otherwise it will be read-only and completely unusable
#[cfg(any(
feature = "std-datetime",
feature = "std-fs",
feature = "std-luau",
feature = "std-net",
feature = "std-process",
feature = "std-regex",
feature = "std-roblox",
feature = "std-serde",
feature = "std-stdio",
feature = "std-task",
))]
{
let g_table = lune_std::LuneStandardGlobal::GTable;
lua.globals()
.set(g_table.name(), g_table.create(lua.clone())?)?;
}
let args = ProcessArgs::current();
let env = ProcessEnv::current();
let jit = ProcessJitEnablement::default();
Ok(Self {
lua,
sched,
args,
env,
jit,
})
}
/**
Sets arguments to give in `process.args` for Lune scripts.
By default, `std::env::args_os()` is used.
*/
#[must_use]
pub fn with_args<A, S>(mut self, args: A) -> Self
where
A: IntoIterator<Item = S>,
S: Into<OsString>,
{
self.args = args.into_iter().map(Into::into).collect();
self
}
/**
Sets environment values to give in `process.env` for Lune scripts.
By default, `std::env::vars_os()` is used.
*/
#[must_use]
pub fn with_env<E, K, V>(mut self, env: E) -> Self
where
E: IntoIterator<Item = (K, V)>,
K: Into<OsString>,
V: Into<OsString>,
{
self.env = env.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
self
}
/**
Enables or disables JIT compilation.
*/
#[must_use]
pub fn with_jit<J>(mut self, jit_status: J) -> Self
where
J: Into<ProcessJitEnablement>,
{
self.jit = jit_status.into();
self
}
/**
Adds a custom library to the runtime, making it available through `require`.
# Example Usage
First, create a library as such:
```rs
Runtime::new().with_lib("@myalias/mylib", |lua| {
let t = lua.create_table()?;
let f = lua.create_function(|lua| {
println!("bar");
Ok(())
})?;
t.set("foo", f)?;
Ok(t)
});
```
Then, use it in Lua:
```luau
local lib = require("@myalias/mylib")
lib.foo() --> "bar"
```
# Errors
Returns an error if:
- The library name does not start with `@`
- The library uses the reserved `lune` alias
- The library uses the reserved `self` alias
- The provided `make_lib` function errors
*/
pub fn with_lib<S, F>(self, name: S, make_lib: F) -> RuntimeResult<Self>
where
S: AsRef<str>,
F: FnOnce(&Lua) -> LuaResult<LuaValue>,
{
let name = name.as_ref().trim();
if !name.starts_with('@') {
return Err(RuntimeError::from(LuaError::external(
"Library names must start with '@'",
)));
}
if name.starts_with("@lune/") {
return Err(RuntimeError::from(LuaError::external(
"Library names must not start with '@lune/'",
)));
}
if name.starts_with("@self/") {
return Err(RuntimeError::from(LuaError::external(
"Library names must not start with '@self/'",
)));
}
let lib = make_lib(&self.lua)?;
self.lua.register_module(name, lib)?;
Ok(self)
}
/**
Runs some kind of custom input, inside of the current runtime.
For any input that is a real module or file path, [`run_file`] should
be used instead, since when using this method, any file requires will
fail. Requires for standard libraries and custom libraries will work.
# Errors
Returns an error if:
- The script fails to run (not if the script itself errors)
*/
pub async fn run_custom(
&mut self,
chunk_name: impl AsRef<str>,
chunk_contents: impl AsRef<[u8]>,
) -> RuntimeResult<RuntimeReturnValues> {
let chunk_name = format!("={}", chunk_name.as_ref());
self.run_inner(chunk_name, chunk_contents).await
}
/**
Runs a file at the given file or module path, inside of the current runtime.
# Errors
Returns an error if:
- The file does not exist or can not be read
- The script fails to run (not if the script itself errors)
*/
pub async fn run_file(
&mut self,
path: impl Into<PathBuf>,
) -> RuntimeResult<RuntimeReturnValues> {
/*
For calls to `require` to resolve properly, we must:
1. Strip any lua/luau extensions, as well as "init" file
segments from the path.
2. Resolve any given file path to the respective "module"
path according to the require-by-string specification.
After doing this, we should end up with both:
- A source (module path)
- A target (file path)
If the given path was already a valid module path,
this should be a no-op.
*/
let module_or_file_path = LuauModulePath::strip(path);
let module_path = LuauModulePath::resolve(&module_or_file_path)
.map_err(|e| LuaError::external(format!("{e:?}")))
.with_context(|_| {
format!(
"Failed to read file at path \"{}\"",
module_or_file_path.display()
)
})?;
let contents = fs::read(module_path.target())
.await
.into_lua_err()
.with_context(|_| {
format!("Failed to read file at path \"{}\"", module_path.target())
})?;
let module_name = format!("{FILE_CHUNK_PREFIX}{module_path}");
let module_contents = strip_shebang(contents);
self.run_inner(module_name, module_contents).await
}
async fn run_inner(
&mut self,
chunk_name: impl AsRef<str>,
chunk_contents: impl AsRef<[u8]>,
) -> RuntimeResult<RuntimeReturnValues> {
// Add error callback to format errors nicely + store status
let got_any_error = Arc::new(AtomicBool::new(false));
let got_any_inner = Arc::clone(&got_any_error);
self.sched.set_error_callback(move |e| {
got_any_inner.store(true, Ordering::SeqCst);
eprintln!("{}", RuntimeError::from(e));
});
// Store the provided args, environment variables, and jit enablement as AppData
self.lua.set_app_data(self.args.clone());
self.lua.set_app_data(self.env.clone());
self.lua.set_app_data(self.jit);
// Inject all the standard libraries that are enabled - this needs to be done after
// storing the args/env, since some standard libraries use those during initialization
#[cfg(any(
feature = "std-datetime",
feature = "std-fs",
feature = "std-luau",
feature = "std-net",
feature = "std-process",
feature = "std-regex",
feature = "std-roblox",
feature = "std-serde",
feature = "std-stdio",
feature = "std-task",
))]
{
lune_std::inject_std(self.lua.clone())?;
}
// Enable / disable the JIT as requested, before loading anything
self.lua.enable_jit(self.jit.enabled());
// Load our "main" thread
let main = self
.lua
.load(chunk_contents.as_ref())
.set_name(chunk_name.as_ref());
// Run it on our scheduler until it and any other spawned threads complete
let main_thread_id = self.sched.push_thread_back(main, ())?;
self.sched.run().await;
let main_thread_values = self
.sched
.get_thread_result(main_thread_id)
.unwrap_or_else(|| Ok(LuaMultiValue::new())) // Ignore missing result (interruption), we just want to extract values
.unwrap_or_default(); // Ignore any errors from the script, we just want to extract values
Ok(RuntimeReturnValues {
code: self.sched.get_exit_code(),
errored: got_any_error.load(Ordering::SeqCst),
values: main_thread_values,
})
}
}
fn strip_shebang(mut contents: Vec<u8>) -> Vec<u8> {
if contents.starts_with(b"#!")
&& let Some(first_newline_idx) = contents
.iter()
.enumerate()
.find_map(|(idx, c)| if *c == b'\n' { Some(idx) } else { None })
{
// NOTE: We keep the newline here on purpose to preserve
// correct line numbers in stack traces, the only reason
// we strip the shebang is to get the lua script to parse
// and the extra newline is not really a problem for that
contents.drain(..first_newline_idx);
}
contents
}
================================================
FILE: crates/lune/src/standalone/metadata.rs
================================================
use std::{env, path::PathBuf, sync::LazyLock};
use anyhow::{Result, bail};
use async_fs as fs;
use mlua::Compiler as LuaCompiler;
pub static CURRENT_EXE: LazyLock<PathBuf> =
LazyLock::new(|| env::current_exe().expect("failed to get current exe"));
const MAGIC: &[u8; 8] = b"cr3sc3nt";
/*
TODO: Right now all we do is append the bytecode to the end
of the binary, but we will need a more flexible solution in
the future to store many files as well as their metadata.
The best solution here is most likely to use a well-supported
and rust-native binary serialization format with a stable
specification, one that also supports byte arrays well without
overhead, so the best solution seems to currently be Postcard:
https://github.com/jamesmunns/postcard
https://crates.io/crates/postcard
*/
/**
Metadata for a standalone Lune executable. Can be used to
discover and load the bytecode contained in a standalone binary.
*/
#[derive(Debug, Clone)]
pub struct Metadata {
pub bytecode: Vec<u8>,
}
impl Metadata {
/**
Returns whether or not the currently executing Lune binary
is a standalone binary, and if so, the bytes of the binary.
*/
pub async fn check_env() -> (bool, Vec<u8>) {
let contents = fs::read(CURRENT_EXE.to_path_buf())
.await
.unwrap_or_default();
let is_standalone = contents.ends_with(MAGIC);
(is_standalone, contents)
}
/**
Creates a patched standalone binary from the given script contents.
*/
pub async fn create_env_patched_bin(
base_exe_path: PathBuf,
script_contents: impl Into<Vec<u8>>,
) -> Result<Vec<u8>> {
let compiler = LuaCompiler::new()
.set_optimization_level(2)
.set_coverage_level(0)
.set_debug_level(1);
let mut patched_bin = fs::read(base_exe_path).await?;
// Compile luau input into bytecode
let bytecode = compiler.compile(script_contents.into())?;
// Append the bytecode / metadata to the end
let meta = Self { bytecode };
patched_bin.extend_from_slice(&meta.to_bytes());
Ok(patched_bin)
}
/**
Tries to read a standalone binary from the given bytes.
*/
pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result<Self> {
let bytes = bytes.as_ref();
if bytes.len() < 16 || !bytes.ends_with(MAGIC) {
bail!("not a standalone binary")
}
// Extract bytecode size
let bytecode_size_bytes = &bytes[bytes.len() - 16..bytes.len() - 8];
let bytecode_size =
usize::try_from(u64::from_be_bytes(bytecode_size_bytes.try_into().unwrap()))?;
// Extract bytecode
let bytecode = bytes[bytes.len() - 16 - bytecode_size..].to_vec();
Ok(Self { bytecode })
}
/**
Writes the metadata chunk to a byte vector, to later bet read using `from_bytes`.
*/
pub fn to_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
bytes.extend_from_slice(&self.bytecode);
bytes.extend_from_slice(&(self.bytecode.len() as u64).to_be_bytes());
bytes.extend_from_slice(MAGIC);
bytes
}
}
================================================
FILE: crates/lune/src/standalone/mod.rs
================================================
use std::{env, process::ExitCode};
use anyhow::Result;
use lune::Runtime;
pub(crate) mod metadata;
pub(crate) mod tracer;
use self::metadata::Metadata;
/**
Returns whether or not the currently executing Lune binary
is a standalone binary, and if so, the bytes of the binary.
*/
pub async fn check() -> Option<Vec<u8>> {
let (is_standalone, patched_bin) = Metadata::check_env().await;
if is_standalone {
Some(patched_bin)
} else {
None
}
}
/**
Discovers, loads and executes the bytecode contained in a standalone binary.
*/
pub async fn run(patched_bin: impl AsRef<[u8]>) -> Result<ExitCode> {
// The first argument is the path to the current executable
let args = env::args().skip(1).collect::<Vec<_>>();
let meta = Metadata::from_bytes(patched_bin).expect("must be a standalone binary");
let mut rt = Runtime::new()?.with_args(args);
let result = rt.run_custom("STANDALONE", meta.bytecode).await;
Ok(match result {
Err(err) => {
eprintln!("{err}");
ExitCode::FAILURE
}
Ok(values) => ExitCode::from(values.status()),
})
}
================================================
FILE: crates/lune/src/standalone/tracer.rs
================================================
/*
TODO: Implement tracing of requires here
Rough steps / outline:
1. Create a new tracer struct using a main entrypoint script path
2. Some kind of discovery mechanism that goes through all require chains (failing on recursive ones)
2a. Conversion of script-relative paths to cwd-relative paths + normalization
2b. Cache all found files in a map of file path -> file contents
2c. Prepend some kind of symbol to paths that can tell our runtime `require` function that it
should look up a bundled/standalone script, a good symbol here is probably a dollar sign ($)
3. ???
4. Profit
*/
================================================
FILE: crates/lune/src/tests.rs
================================================
use std::env::set_current_dir;
use std::path::PathBuf;
use std::process::ExitCode;
use anyhow::Result;
use console::set_colors_enabled;
use console::set_colors_enabled_stderr;
use lune_utils::path::clean_path;
use crate::Runtime;
const ARGS: &[&str] = &["Foo", "Bar"];
fn run_test(path: &str) -> Result<ExitCode> {
async_io::block_on(async {
// We need to change the current directory to the workspace root since
// we are in a sub-crate and tests would run relative to the sub-crate
let workspace_dir_str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../");
let workspace_dir = clean_path(PathBuf::from(workspace_dir_str));
set_current_dir(&workspace_dir)?;
// Disable styling for stdout and stderr since
// some tests rely on output not being styled
set_colors_enabled(false);
set_colors_enabled_stderr(false);
// The rest of the test logic can continue as normal
let mut rt = Runtime::new()?.with_args(ARGS).with_jit(true);
let script_path = workspace_dir.join("tests").join(format!("{path}.luau"));
let script_values = rt.run_file(script_path).await?;
Ok(ExitCode::from(script_values.status()))
})
}
macro_rules! create_tests {
($($name:ident: $value:expr,)*) => { $(
#[test]
fn $name() -> Result<ExitCode> {
run_test($value)
}
)* }
}
#[cfg(any(
feature = "std-datetime",
feature = "std-fs",
feature = "std-luau",
feature = "std-net",
feature = "std-process",
feature = "std-regex",
feature = "std-roblox",
feature = "std-serde",
feature = "std-stdio",
feature = "std-task",
))]
create_tests! {
require_aliases: "require/tests/aliases",
require_async: "require/tests/async",
require_async_concurrent: "require/tests/async_concurrent",
require_async_sequential: "require/tests/async_sequential",
require_builtins: "require/tests/builtins",
require_children: "require/tests/children",
require_init: "require/tests/init_files",
require_invalid: "require/tests/invalid",
require_multi_ext: "require/tests/multi_ext",
require_nested: "require/tests/nested",
require_parents: "require/tests/parents",
require_siblings: "require/tests/siblings",
require_state: "require/tests/state",
global_g_table: "globals/_G",
global_version: "globals/_VERSION",
global_coroutine: "globals/coroutine",
global_error: "globals/error",
global_pcall: "globals/pcall",
global_type: "globals/type",
global_typeof: "globals/typeof",
global_warn: "globals/warn",
}
#[cfg(feature = "std-datetime")]
create_tests! {
datetime_format_local_time: "datetime/formatLocalTime",
datetime_format_universal_time: "datetime/formatUniversalTime",
datetime_from_rfc_2822: "datetime/fromRfc2822",
datetime_from_rfc_3339: "datetime/fromRfc3339",
datetime_from_local_time: "datetime/fromLocalTime",
datetime_from_universal_time: "datetime/fromUniversalTime",
datetime_from_unix_timestamp: "datetime/fromUnixTimestamp",
datetime_now: "datetime/now",
datetime_to_rfc_2822: "datetime/toRfc2822",
datetime_to_rfc_3339: "datetime/toRfc3339",
datetime_to_local_time: "datetime/toLocalTime",
datetime_to_universal_time: "datetime/toUniversalTime",
}
#[cfg(feature = "std-fs")]
create_tests! {
fs_files: "fs/files",
fs_copy: "fs/copy",
fs_dirs: "fs/dirs",
fs_metadata: "fs/metadata",
fs_move: "fs/move",
}
#[cfg(feature = "std-luau")]
create_tests! {
luau_compile: "luau/compile",
luau_load: "luau/load",
luau_options: "luau/options",
luau_safeenv: "luau/safeenv",
}
#[cfg(feature = "std-net")]
create_tests! {
net_request_codes: "net/request/codes",
net_request_compression: "net/request/compression",
net_request_https: "net/request/https",
net_request_methods: "net/request/methods",
net_request_query: "net/request/query",
net_request_redirect: "net/request/redirect",
net_serve_addresses: "net/serve/addresses",
net_serve_handles: "net/serve/handles",
net_serve_non_blocking: "net/serve/non_blocking",
net_serve_requests: "net/serve/requests",
net_serve_websockets: "net/serve/websockets",
net_socket_basic: "net/socket/basic",
net_socket_wss: "net/socket/wss",
net_socket_wss_rw: "net/socket/wss_rw",
net_tcp_basic: "net/tcp/basic",
net_tcp_info: "net/tcp/info",
net_tcp_tls: "net/tcp/tls",
net_url_encode: "net/url/encode",
net_url_decode: "net/url/decode",
}
#[cfg(feature = "std-process")]
create_tests! {
process_args: "process/args",
process_cwd: "process/cwd",
process_env: "process/env",
process_exit: "process/exit",
process_exec_async: "process/exec/async",
process_exec_basic: "process/exec/basic",
process_exec_cwd: "process/exec/cwd",
process_exec_no_panic: "process/exec/no_panic",
process_exec_shell: "process/exec/shell",
process_exec_stdin: "process/exec/stdin",
process_exec_stdio: "process/exec/stdio",
process_spawn_non_blocking: "process/create/non_blocking",
process_spawn_status: "process/create/status",
process_spawn_stream: "process/create/stream",
}
#[cfg(feature = "std-regex")]
create_tests! {
regex_general: "regex/general",
regex_metamethods: "regex/metamethods",
regex_replace: "regex/replace",
}
#[cfg(feature = "std-roblox")]
create_tests! {
roblox_datatype_axes: "roblox/datatypes/Axes",
roblox_datatype_brick_color: "roblox/datatypes/BrickColor",
roblox_datatype_cframe: "roblox/datatypes/CFrame",
roblox_datatype_color3: "roblox/datatypes/Color3",
roblox_datatype_color_sequence: "roblox/datatypes/ColorSequence",
roblox_datatype_color_sequence_keypoint: "roblox/datatypes/ColorSequenceKeypoint",
roblox_datatype_content: "roblox/datatypes/Content",
roblox_datatype_enum: "roblox/datatypes/Enum",
roblox_datatype_faces: "roblox/datatypes/Faces",
roblox_datatype_font: "roblox/datatypes/Font",
roblox_datatype_number_range: "roblox/datatypes/NumberRange",
roblox_datatype_number_sequence: "roblox/datatypes/NumberSequence",
roblox_datatype_number_sequence_keypoint: "roblox/datatypes/NumberSequenceKeypoint",
roblox_datatype_physical_properties: "roblox/datatypes/PhysicalProperties",
roblox_datatype_ray: "roblox/datatypes/Ray",
roblox_datatype_rect: "roblox/datatypes/Rect",
roblox_datatype_udim: "roblox/datatypes/UDim",
roblox_datatype_udim2: "roblox/datatypes/UDim2",
roblox_datatype_uniqueid: "roblox/datatypes/UniqueId",
roblox_datatype_region3: "roblox/datatypes/Region3",
roblox_datatype_region3int16: "roblox/datatypes/Region3int16",
roblox_datatype_vector2: "roblox/datatypes/Vector2",
roblox_datatype_vector2int16: "roblox/datatypes/Vector2int16",
roblox_datatype_vector3: "roblox/datatypes/Vector3",
roblox_datatype_vector3int16: "roblox/datatypes/Vector3int16",
roblox_files_deserialize_model: "roblox/files/deserializeModel",
roblox_files_deserialize_place: "roblox/files/deserializePlace",
roblox_files_serialize_model: "roblox/files/serializeModel",
roblox_files_serialize_place: "roblox/files/serializePlace",
roblox_instance_attributes: "roblox/instance/attributes",
roblox_instance_new: "roblox/instance/new",
roblox_instance_properties: "roblox/instance/properties",
roblox_instance_tags: "roblox/instance/tags",
roblox_instance_classes_data_model: "roblox/instance/classes/DataModel",
roblox_instance_classes_workspace: "roblox/instance/classes/Workspace",
roblox_instance_classes_terrain: "roblox/instance/classes/Terrain",
roblox_instance_custom_async: "roblox/instance/custom/async",
roblox_instance_custom_methods: "roblox/instance/custom/methods",
roblox_instance_custom_properties: "roblox/instance/custom/properties",
roblox_instance_methods_clear_all_children: "roblox/instance/methods/ClearAllChildren",
roblox_instance_methods_clone: "roblox/instance/methods/Clone",
roblox_instance_methods_destroy: "roblox/instance/methods/Destroy",
roblox_instance_methods_find_first_ancestor: "roblox/instance/methods/FindFirstAncestor",
roblox_instance_methods_find_first_ancestor_of_class: "roblox/instance/methods/FindFirstAncestorOfClass",
roblox_instance_methods_find_first_ancestor_which_is_a: "roblox/instance/methods/FindFirstAncestorWhichIsA",
roblox_instance_methods_find_first_child: "roblox/instance/methods/FindFirstChild",
roblox_instance_methods_find_first_child_of_class: "roblox/instance/methods/FindFirstChildOfClass",
roblox_instance_methods_find_first_child_which_is_a: "roblox/instance/methods/FindFirstChildWhichIsA",
roblox_instance_methods_get_children: "roblox/instance/methods/GetChildren",
roblox_instance_methods_get_debug_id: "roblox/instance/methods/GetDebugId",
roblox_instance_methods_get_descendants: "roblox/instance/methods/GetDescendants",
roblox_instance_methods_get_full_name: "roblox/instance/methods/GetFullName",
roblox_instance_methods_is_a: "roblox/instance/methods/IsA",
roblox_instance_methods_is_ancestor_of: "roblox/instance/methods/IsAncestorOf",
roblox_instance_methods_is_descendant_of: "roblox/instance/methods/IsDescendantOf",
roblox_misc_typeof: "roblox/misc/typeof",
roblox_reflection_class: "roblox/reflection/class",
roblox_reflection_database: "roblox/reflection/database",
roblox_reflection_enums: "roblox/reflection/enums",
roblox_reflection_property: "roblox/reflection/property",
}
#[cfg(feature = "std-serde")]
create_tests! {
serde_compression_files: "serde/compression/files",
serde_compression_roundtrip: "serde/compression/roundtrip",
serde_json_decode: "serde/json/decode",
serde_json_encode: "serde/json/encode",
serde_jsonc_decode: "serde/jsonc/decode",
serde_jsonc_encode: "serde/jsonc/encode",
serde_toml_decode: "serde/toml/decode",
serde_toml_encode: "serde/toml/encode",
serde_hashing_hash: "serde/hashing/hash",
serde_hashing_hmac: "serde/hashing/hmac",
}
#[cfg(feature = "std-stdio")]
create_tests! {
stdio_format: "stdio/format",
stdio_color: "stdio/color",
stdio_style: "stdio/style",
stdio_write: "stdio/write",
stdio_ewrite: "stdio/ewrite",
}
#[cfg(feature = "std-task")]
create_tests! {
task_cancel: "task/cancel",
task_defer: "task/defer",
task_delay: "task/delay",
task_spawn: "task/spawn",
task_wait: "task/wait",
}
================================================
FILE: crates/lune-roblox/Cargo.toml
================================================
[package]
name = "lune-roblox"
version = "0.3.4"
edition = "2024"
license = "MPL-2.0"
repository = "https://github.com/lune-org/lune"
description = "Roblox library for Lune"
[lib]
path = "src/lib.rs"
[lints]
workspace = true
[features]
default = ["mlua"]
mlua = ["dep:mlua", "dep:lune-utils"]
[dependencies]
mlua = { version = "0.11.4", optional = true, features = ["luau"] }
glam = "0.30"
rand = "0.9"
thiserror = "2.0"
rbx_binary = "2.0"
rbx_dom_weak = "4.0"
rbx_reflection = "6.0"
rbx_reflection_database = "2.0"
rbx_xml = "2.0"
lune-utils = { version = "0.3.4", optional = true, path = "../lune-utils" }
================================================
FILE: crates/lune-roblox/src/datatypes/attributes.rs
================================================
use mlua::prelude::*;
use rbx_dom_weak::types::{Variant as DomValue, VariantType as DomType};
use super::extension::DomValueExt;
/**
Checks if the given name is a valid attribute name.
# Errors
- If the name starts with the prefix "RBX".
- If the name contains any characters other than alphanumeric characters, periods, hyphens, underscores, or forward slashes.
- If the name is longer than 100 characters.
*/
pub fn ensure_valid_attribute_name(name: impl AsRef<str>) -> LuaResult<()> {
let name = name.as_ref();
if name.to_ascii_uppercase().starts_with("RBX") {
Err(LuaError::RuntimeError(
"Attribute names must not start with the prefix \"RBX\"".to_string(),
))
} else if !name
.chars()
.all(|c| c.is_alphanumeric() || matches!(c, '.' | '_' | '-' | '/'))
{
Err(LuaError::RuntimeError(
"Attribute names must only use alphanumeric characters, periods, hyphens, underscores, or forward slashes.".to_string(),
))
} else if name.len() > 100 {
Err(LuaError::RuntimeError(
"Attribute names must be 100 characters or less in length".to_string(),
))
} else {
Ok(())
}
}
/**
Checks if the given value is a valid attribute value.
# Errors
- If the value is not a valid attribute type.
*/
pub fn ensure_valid_attribute_value(value: &DomValue) -> LuaResult<()> {
let is_valid = matches!(
value.ty(),
DomType::Bool
| DomType::BrickColor
| DomType::CFrame
| DomType::Color3
| DomType::ColorSequence
| DomType::EnumItem
| DomType::Float32
| DomType::Float64
| DomType::Font
| DomType::Int32
| DomType::Int64
| DomType::NumberRange
| DomType::NumberSequence
| DomType::Rect
| DomType::String
| DomType::UDim
| DomType::UDim2
| DomType::Vector2
| DomType::Vector3
);
if is_valid {
Ok(())
} else {
Err(LuaError::RuntimeError(format!(
"'{}' is not a valid attribute type",
value.ty().variant_name().unwrap_or("???")
)))
}
}
================================================
FILE: crates/lune-roblox/src/datatypes/conversion.rs
================================================
use mlua::prelude::*;
use rbx_dom_weak::types::{Variant as DomValue, VariantType as DomType};
use crate::{datatypes::extension::DomValueExt, instance::Instance};
use super::*;
pub(crate) trait LuaToDomValue {
/**
Converts a lua value into a weak dom value.
If a `variant_type` is given the conversion will be more strict
and also more accurate, it should be given whenever possible.
*/
fn lua_to_dom_value(
&self,
lua: &Lua,
variant_type: Option<DomType>,
) -> DomConversionResult<DomValue>;
}
pub(crate) trait DomValueToLua: Sized {
/**
Converts a weak dom value into a lua value.
*/
fn dom_value_to_lua(lua: &Lua, variant: &DomValue) -> DomConversionResult<Self>;
}
/*
Blanket trait implementations for converting between LuaValue and rbx_dom Variant values
These should be considered stable and done, already containing all of the known primitives
See bottom of module for implementations between our custom datatypes and lua userdata
*/
impl DomValueToLua for LuaValue {
fn dom_value_to_lua(lua: &Lua, variant: &DomValue) -> DomConversionResult<Self> {
use rbx_dom_weak::types as dom;
match LuaAnyUserData::dom_value_to_lua(lua, variant) {
Ok(value) => Ok(LuaValue::UserData(value)),
Err(e) => match variant {
DomValue::Bool(b) => Ok(LuaValue::Boolean(*b)),
DomValue::Int64(i) => Ok(LuaValue::Number(*i as f64)),
DomValue::Int32(i) => Ok(LuaValue::Number(*i as f64)),
DomValue::Float64(n) => Ok(LuaValue::Number(*n)),
DomValue::Float32(n) => Ok(LuaValue::Number(*n as f64)),
DomValue::String(s) => Ok(LuaValue::String(lua.create_string(s)?)),
DomValue::BinaryString(s) => Ok(LuaValue::String(lua.create_string(s)?)),
DomValue::ContentId(s) => Ok(LuaValue::String(
lua.create_string(AsRef::<str>::as_ref(s))?,
)),
// NOTE: Dom references may point to instances that
// no longer exist, so we handle that here instead of
// in the userdata conversion to be able to return nils
DomValue::Ref(value) => match Instance::new_opt(*value) {
Some(inst) => Ok(inst.into_lua(lua)?),
None => Ok(LuaValue::Nil),
},
// NOTE: Some values are either optional or default and we should handle
// that properly here since the userdata conversion above will always fail
DomValue::OptionalCFrame(None)
| DomValue::PhysicalProperties(dom::PhysicalProperties::Default) => {
Ok(LuaValue::Nil)
}
_ => Err(e),
},
}
}
}
impl LuaToDomValue for LuaValue {
fn lua_to_dom_value(
&self,
lua: &Lua,
variant_type: Option<DomType>,
) -> DomConversionResult<DomValue> {
use rbx_dom_weak::types as dom;
if let Some(variant_type) = variant_type {
match (self, variant_type) {
(LuaValue::Boolean(b), DomType::Bool) => Ok(DomValue::Bool(*b)),
(LuaValue::Integer(i), DomType::Int64) => Ok(DomValue::Int64(*i)),
(LuaValue::Integer(i), DomType::Int32) => Ok(DomValue::Int32(*i as i32)),
(LuaValue::Integer(i), DomType::Float64) => Ok(DomValue::Float64(*i as f64)),
(LuaValue::Integer(i), DomType::Float32) => Ok(DomValue::Float32(*i as f32)),
(LuaValue::Number(n), DomType::Int64) => Ok(DomValue::Int64(*n as i64)),
(LuaValue::Number(n), DomType::Int32) => Ok(DomValue::Int32(*n as i32)),
(LuaValue::Number(n), DomType::Float64) => Ok(DomValue::Float64(*n)),
(LuaValue::Number(n), DomType::Float32) => Ok(DomValue::Float32(*n as f32)),
(LuaValue::String(s), DomType::String) => {
Ok(DomValue::String(s.to_str()?.to_string()))
}
(LuaValue::String(s), DomType::BinaryString) => {
Ok(DomValue::BinaryString(s.as_bytes().to_vec().into()))
}
(LuaValue::String(s), DomType::ContentId) => {
Ok(DomValue::ContentId(s.to_str()?.to_string().into()))
}
// NOTE: Some values are either optional or default and we
// should handle that here before trying to convert as userdata
(LuaValue::Nil, DomType::OptionalCFrame) => Ok(DomValue::OptionalCFrame(None)),
(LuaValue::Nil, DomType::PhysicalProperties) => Ok(DomValue::PhysicalProperties(
dom::PhysicalProperties::Default,
)),
(LuaValue::UserData(u), d) => u.lua_to_dom_value(lua, Some(d)),
(v, d) => Err(DomConversionError::ToDomValue {
to: d.variant_name().unwrap_or("???"),
from: v.type_name(),
detail: None,
}),
}
} else {
match self {
LuaValue::Boolean(b) => Ok(DomValue::Bool(*b)),
LuaValue::Integer(i) => Ok(DomValue::Int32(*i as i32)),
LuaValue::Number(n) => Ok(DomValue::Float64(*n)),
LuaValue::String(s) => Ok(DomValue::String(s.to_str()?.to_string())),
LuaValue::UserData(u) => u.lua_to_dom_value(lua, None),
v => Err(DomConversionError::ToDomValue {
to: "unknown",
from: v.type_name(),
detail: None,
}),
}
}
}
}
/*
Trait implementations for converting between all of
our custom datatypes and generic Lua userdata values
NOTE: When adding a new datatype, make sure to add it below to _both_
of the traits and not just one to allow for bidirectional conversion
*/
macro_rules! dom_to_userdata {
($lua:expr, $value:ident => $to_type:ty) => {
Ok($lua.create_userdata(Into::<$to_type>::into($value.clone()))?)
};
}
/**
Converts a generic lua userdata to an rbx-dom type.
Since the type of the userdata needs to be specified
in an explicit manner, this macro syntax was chosen:
```rs
userdata_to_dom!(value_identifier as UserdataType => DomType)
```
*/
macro_rules! userdata_to_dom {
($userdata:ident as $from_type:ty => $to_type:ty) => {
match $userdata.borrow::<$from_type>() {
Ok(value) => Ok(From::<$to_type>::from(value.clone().into())),
Err(error) => match error {
LuaError::UserDataTypeMismatch => Err(DomConversionError::ToDomValue {
to: stringify!($to_type),
from: "userdata",
detail: Some("Type mismatch".to_string()),
}),
e => Err(DomConversionError::ToDomValue {
to: stringify!($to_type),
from: "userdata",
detail: Some(format!("Internal error: {e}")),
}),
},
}
};
}
impl DomValueToLua for LuaAnyUserData {
#[allow(clippy::match_same_arms)]
#[rustfmt::skip]
fn dom_value_to_lua(lua: &Lua, variant: &DomValue) -> DomConversionResult<Self> {
use super::types::*;
use rbx_dom_weak::types as dom;
match variant {
DomValue::Axes(value) => dom_to_userdata!(lua, value => Axes),
DomValue::BrickColor(value) => dom_to_userdata!(lua, value => BrickColor),
DomValue::CFrame(value) => dom_to_userdata!(lua, value => CFrame),
DomValue::Color3(value) => dom_to_userdata!(lua, value => Color3),
DomValue::Color3uint8(value) => dom_to_userdata!(lua, value => Color3),
DomValue::ColorSequence(value) => dom_to_userdata!(lua, value => ColorSequence),
DomValue::Content(value) => dom_to_userdata!(lua, value => Content),
DomValue::EnumItem(value) => dom_to_userdata!(lua, value => EnumItem),
DomValue::Faces(value) => dom_to_userdata!(lua, value => Faces),
DomValue::Font(value) => dom_to_userdata!(lua, value => Font),
DomValue::NumberRange(value) => dom_to_userdata!(lua, value => NumberRange),
DomValue::NumberSequence(value) => dom_to_userdata!(lua, value => NumberSequence),
DomValue::Ray(value) => dom_to_userdata!(lua, value => Ray),
DomValue::Rect(value) => dom_to_userdata!(lua, value => Rect),
DomValue::Region3(value) => dom_to_userdata!(lua, value => Region3),
DomValue::Region3int16(value) => dom_to_userdata!(lua, value => Region3int16),
DomValue::UDim(value) => dom_to_userdata!(lua, value => UDim),
DomValue::UDim2(value) => dom_to_userdata!(lua, value => UDim2),
DomValue::UniqueId(value) => dom_to_userdata!(lua, value => UniqueId),
DomValue::Vector2(value) => dom_to_userdata!(lua, value => Vector2),
DomValue::Vector2int16(value) => dom_to_userdata!(lua, value => Vector2int16),
DomValue::Vector3(value) => dom_to_userdata!(lua, value => Vector3),
DomValue::Vector3int16(value) => dom_to_userdata!(lua, value => Vector3int16),
// NOTE: The none and default variants of these types are handled in
// DomValueToLua for the LuaValue type instead, allowing for nil/default
DomValue::OptionalCFrame(Some(value)) => dom_to_userdata!(lua, value => CFrame),
DomValue::PhysicalProperties(dom::PhysicalProperties::Custom(value)) => {
dom_to_userdata!(lua, value => PhysicalProperties)
},
v => {
Err(DomConversionError::FromDomValue {
from: v.variant_name().unwrap_or("???"),
to: "userdata",
detail: Some("Type not supported".to_string()),
})
}
}
}
}
impl LuaToDomValue for LuaAnyUserData {
#[rustfmt::skip]
fn lua_to_dom_value(&self, _: &Lua, variant_type: Option<DomType>) -> DomConversionResult<DomValue> {
use super::types::*;
use rbx_dom_weak::types as dom;
if let Some(variant_type) = variant_type {
/*
Strict target type, use it to skip checking the actual
type of the userdata and try to just do a pure conversion
*/
match variant_type {
DomType::Axes => userdata_to_dom!(self as Axes => dom::Axes),
DomType::BrickColor => userdata_to_dom!(self as BrickColor => dom::BrickColor),
DomType::CFrame => userdata_to_dom!(self as CFrame => dom::CFrame),
DomType::Color3 => userdata_to_dom!(self as Color3 => dom::Color3),
DomType::Color3uint8 => userdata_to_dom!(self as Color3 => dom::Color3uint8),
DomType::ColorSequence => userdata_to_dom!(self as ColorSequence => dom::ColorSequence),
DomType::Content => userdata_to_dom!(self as Content => dom::Content),
DomType::EnumItem => userdata_to_dom!(self as EnumItem => dom::EnumItem),
DomType::Faces => userdata_to_dom!(self as Faces => dom::Faces),
DomType::Font => userdata_to_dom!(self as Font => dom::Font),
DomType::NumberRange => userdata_to_dom!(self as NumberRange => dom::NumberRange),
DomType::NumberSequence => userdata_to_dom!(self as NumberSequence => dom::NumberSequence),
DomType::Ray => userdata_to_dom!(self as Ray => dom::Ray),
DomType::Rect => userdata_to_dom!(self as Rect => dom::Rect),
DomType::Ref => userdata_to_dom!(self as Instance => dom::Ref),
DomType::Region3 => userdata_to_dom!(self as Region3 => dom::Region3),
DomType::Region3int16 => userdata_to_dom!(self as Region3int16 => dom::Region3int16),
DomType::UDim => userdata_to_dom!(self as UDim => dom::UDim),
DomType::UDim2 => userdata_to_dom!(self as UDim2
gitextract_9kvtan03/
├── .cargo/
│ └── config.toml
├── .editorconfig
├── .gitattributes
├── .github/
│ └── workflows/
│ ├── ci.yaml
│ └── release.yaml
├── .gitignore
├── .gitmodules
├── .luaurc
├── .lune/
│ ├── csv_printer.luau
│ ├── data/
│ │ └── test.csv
│ ├── hello_lune.luau
│ ├── http_server.luau
│ ├── websocket_client.luau
│ └── websocket_server.luau
├── .vscode/
│ ├── extensions.json
│ └── settings.json
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Cargo.toml
├── LICENSE.txt
├── README.md
├── crates/
│ ├── lune/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── cli/
│ │ │ ├── build/
│ │ │ │ ├── base_exe.rs
│ │ │ │ ├── files.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── result.rs
│ │ │ │ └── target.rs
│ │ │ ├── list.rs
│ │ │ ├── mod.rs
│ │ │ ├── repl.rs
│ │ │ ├── run.rs
│ │ │ ├── setup.rs
│ │ │ └── utils/
│ │ │ ├── files.rs
│ │ │ ├── listing.rs
│ │ │ └── mod.rs
│ │ ├── lib.rs
│ │ ├── main.rs
│ │ ├── rt/
│ │ │ ├── mod.rs
│ │ │ ├── result.rs
│ │ │ └── runtime.rs
│ │ ├── standalone/
│ │ │ ├── metadata.rs
│ │ │ ├── mod.rs
│ │ │ └── tracer.rs
│ │ └── tests.rs
│ ├── lune-roblox/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── datatypes/
│ │ │ ├── attributes.rs
│ │ │ ├── conversion.rs
│ │ │ ├── extension.rs
│ │ │ ├── mod.rs
│ │ │ ├── result.rs
│ │ │ ├── types/
│ │ │ │ ├── axes.rs
│ │ │ │ ├── brick_color.rs
│ │ │ │ ├── cframe.rs
│ │ │ │ ├── color3.rs
│ │ │ │ ├── color_sequence.rs
│ │ │ │ ├── color_sequence_keypoint.rs
│ │ │ │ ├── content.rs
│ │ │ │ ├── enum.rs
│ │ │ │ ├── enum_item.rs
│ │ │ │ ├── enums.rs
│ │ │ │ ├── faces.rs
│ │ │ │ ├── font.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── number_range.rs
│ │ │ │ ├── number_sequence.rs
│ │ │ │ ├── number_sequence_keypoint.rs
│ │ │ │ ├── physical_properties.rs
│ │ │ │ ├── ray.rs
│ │ │ │ ├── rect.rs
│ │ │ │ ├── region3.rs
│ │ │ │ ├── region3int16.rs
│ │ │ │ ├── udim.rs
│ │ │ │ ├── udim2.rs
│ │ │ │ ├── unique_id.rs
│ │ │ │ ├── vector2.rs
│ │ │ │ ├── vector2int16.rs
│ │ │ │ ├── vector3.rs
│ │ │ │ └── vector3int16.rs
│ │ │ └── util.rs
│ │ ├── document/
│ │ │ ├── error.rs
│ │ │ ├── format.rs
│ │ │ ├── kind.rs
│ │ │ ├── mod.rs
│ │ │ └── postprocessing.rs
│ │ ├── exports.rs
│ │ ├── instance/
│ │ │ ├── base.rs
│ │ │ ├── data_model.rs
│ │ │ ├── mod.rs
│ │ │ ├── registry.rs
│ │ │ ├── terrain.rs
│ │ │ └── workspace.rs
│ │ ├── lib.rs
│ │ ├── reflection/
│ │ │ ├── class.rs
│ │ │ ├── enums.rs
│ │ │ ├── mod.rs
│ │ │ ├── property.rs
│ │ │ └── utils.rs
│ │ └── shared/
│ │ ├── classes.rs
│ │ ├── instance.rs
│ │ ├── mod.rs
│ │ └── userdata.rs
│ ├── lune-std/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── global.rs
│ │ ├── globals/
│ │ │ ├── g_table.rs
│ │ │ ├── mod.rs
│ │ │ ├── print.rs
│ │ │ ├── require.rs
│ │ │ ├── version.rs
│ │ │ └── warn.rs
│ │ ├── lib.rs
│ │ ├── library.rs
│ │ └── require/
│ │ ├── loader.rs
│ │ ├── mod.rs
│ │ └── resolver.rs
│ ├── lune-std-datetime/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── date_time.rs
│ │ │ ├── lib.rs
│ │ │ ├── result.rs
│ │ │ └── values.rs
│ │ └── types.d.luau
│ ├── lune-std-fs/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── copy.rs
│ │ │ ├── lib.rs
│ │ │ ├── metadata.rs
│ │ │ └── options.rs
│ │ └── types.d.luau
│ ├── lune-std-luau/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── lib.rs
│ │ │ └── options.rs
│ │ └── types.d.luau
│ ├── lune-std-net/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── body/
│ │ │ │ ├── cursor.rs
│ │ │ │ ├── incoming.rs
│ │ │ │ ├── inner.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── readable.rs
│ │ │ ├── client/
│ │ │ │ ├── fetch.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── rustls.rs
│ │ │ │ ├── send.rs
│ │ │ │ ├── stream.rs
│ │ │ │ └── tcp.rs
│ │ │ ├── lib.rs
│ │ │ ├── server/
│ │ │ │ ├── config.rs
│ │ │ │ ├── handle.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── service.rs
│ │ │ │ └── upgrade.rs
│ │ │ ├── shared/
│ │ │ │ ├── futures.rs
│ │ │ │ ├── headers.rs
│ │ │ │ ├── hyper.rs
│ │ │ │ ├── lua.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── request.rs
│ │ │ │ ├── response.rs
│ │ │ │ ├── tcp.rs
│ │ │ │ └── websocket.rs
│ │ │ └── url/
│ │ │ ├── decode.rs
│ │ │ ├── encode.rs
│ │ │ └── mod.rs
│ │ └── types.d.luau
│ ├── lune-std-process/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── create/
│ │ │ │ ├── child.rs
│ │ │ │ ├── child_reader.rs
│ │ │ │ ├── child_writer.rs
│ │ │ │ └── mod.rs
│ │ │ ├── exec/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── tee_writer.rs
│ │ │ │ └── wait_for_child.rs
│ │ │ ├── lib.rs
│ │ │ └── options/
│ │ │ ├── kind.rs
│ │ │ ├── mod.rs
│ │ │ └── stdio.rs
│ │ └── types.d.luau
│ ├── lune-std-regex/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── captures.rs
│ │ │ ├── lib.rs
│ │ │ ├── matches.rs
│ │ │ └── regex.rs
│ │ └── types.d.luau
│ ├── lune-std-roblox/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ └── lib.rs
│ │ └── types.d.luau
│ ├── lune-std-serde/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── compress_decompress.rs
│ │ │ ├── encode_decode.rs
│ │ │ ├── hash.rs
│ │ │ └── lib.rs
│ │ └── types.d.luau
│ ├── lune-std-stdio/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── lib.rs
│ │ │ ├── prompt.rs
│ │ │ └── style_and_color.rs
│ │ └── types.d.luau
│ ├── lune-std-task/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ └── lib.rs
│ │ └── types.d.luau
│ ├── lune-utils/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── fmt/
│ │ │ ├── error/
│ │ │ │ ├── components.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── stack_trace.rs
│ │ │ │ └── tests.rs
│ │ │ ├── label.rs
│ │ │ ├── mod.rs
│ │ │ └── value/
│ │ │ ├── basic.rs
│ │ │ ├── config.rs
│ │ │ ├── metamethods.rs
│ │ │ ├── mod.rs
│ │ │ ├── recursive.rs
│ │ │ └── style.rs
│ │ ├── lib.rs
│ │ ├── path/
│ │ │ ├── constants.rs
│ │ │ ├── luau.rs
│ │ │ ├── mod.rs
│ │ │ └── std.rs
│ │ ├── process/
│ │ │ ├── args.rs
│ │ │ ├── env.rs
│ │ │ ├── jit.rs
│ │ │ └── mod.rs
│ │ ├── table_builder.rs
│ │ └── version_string.rs
│ └── mlua-luau-scheduler/
│ ├── Cargo.toml
│ ├── README.md
│ ├── examples/
│ │ ├── basic_sleep.rs
│ │ ├── basic_spawn.rs
│ │ ├── callbacks.rs
│ │ ├── exit_code.rs
│ │ ├── lots_of_threads.rs
│ │ ├── lua/
│ │ │ ├── basic_sleep.luau
│ │ │ ├── basic_spawn.luau
│ │ │ ├── callbacks.luau
│ │ │ ├── exit_code.luau
│ │ │ ├── lots_of_threads.luau
│ │ │ └── scheduler_ordering.luau
│ │ ├── scheduler_ordering.rs
│ │ └── tracy.rs
│ └── src/
│ ├── error_callback.rs
│ ├── events/
│ │ ├── mod.rs
│ │ ├── multi.rs
│ │ └── once.rs
│ ├── exit.rs
│ ├── functions.rs
│ ├── lib.rs
│ ├── queue/
│ │ ├── deferred.rs
│ │ ├── futures.rs
│ │ ├── mod.rs
│ │ ├── spawned.rs
│ │ └── threads.rs
│ ├── scheduler.rs
│ ├── status.rs
│ ├── threads/
│ │ ├── id.rs
│ │ ├── map.rs
│ │ └── mod.rs
│ ├── traits.rs
│ └── util.rs
├── rokit.toml
├── scripts/
│ ├── analyze.sh
│ ├── analyze_copy_typedefs.luau
│ ├── brick_color.luau
│ ├── font_enum_map.luau
│ ├── format-check.sh
│ ├── format.sh
│ ├── generate_compression_test_files.luau
│ ├── get-version.sh
│ ├── physical_properties_enum_map.luau
│ ├── unpack-releases.sh
│ └── zip-release.sh
├── stylua.toml
└── tests/
├── datetime/
│ ├── formatLocalTime.luau
│ ├── formatUniversalTime.luau
│ ├── fromLocalTime.luau
│ ├── fromRfc2822.luau
│ ├── fromRfc3339.luau
│ ├── fromUniversalTime.luau
│ ├── fromUnixTimestamp.luau
│ ├── now.luau
│ ├── toLocalTime.luau
│ ├── toRfc2822.luau
│ ├── toRfc3339.luau
│ └── toUniversalTime.luau
├── fs/
│ ├── copy.luau
│ ├── dirs.luau
│ ├── files.luau
│ ├── metadata.luau
│ ├── move.luau
│ └── utils.luau
├── globals/
│ ├── _G.luau
│ ├── _VERSION.luau
│ ├── coroutine.luau
│ ├── error.luau
│ ├── pcall.luau
│ ├── type.luau
│ ├── typeof.luau
│ └── warn.luau
├── luau/
│ ├── compile.luau
│ ├── load.luau
│ ├── options.luau
│ └── safeenv.luau
├── net/
│ ├── request/
│ │ ├── codes.luau
│ │ ├── compression.luau
│ │ ├── https.luau
│ │ ├── methods.luau
│ │ ├── query.luau
│ │ ├── redirect.luau
│ │ ├── user_agent.luau
│ │ └── util.luau
│ ├── serve/
│ │ ├── addresses.luau
│ │ ├── handles.luau
│ │ ├── non_blocking.luau
│ │ ├── requests.luau
│ │ └── websockets.luau
│ ├── socket/
│ │ ├── basic.luau
│ │ ├── wss.luau
│ │ └── wss_rw.luau
│ ├── tcp/
│ │ ├── basic.luau
│ │ ├── info.luau
│ │ └── tls.luau
│ └── url/
│ ├── decode.luau
│ └── encode.luau
├── process/
│ ├── args.luau
│ ├── create/
│ │ ├── kill.luau
│ │ ├── non_blocking.luau
│ │ ├── status.luau
│ │ └── stream.luau
│ ├── cwd.luau
│ ├── env.luau
│ ├── exec/
│ │ ├── async.luau
│ │ ├── basic.luau
│ │ ├── cwd.luau
│ │ ├── no_panic.luau
│ │ ├── shell.luau
│ │ ├── stdin.luau
│ │ └── stdio.luau
│ └── exit.luau
├── regex/
│ ├── general.luau
│ ├── metamethods.luau
│ └── replace.luau
├── require/
│ ├── modules/
│ │ ├── init.luau
│ │ └── module.luau
│ └── tests/
│ ├── aliases.luau
│ ├── async.luau
│ ├── async_concurrent.luau
│ ├── async_sequential.luau
│ ├── builtins.luau
│ ├── children.luau
│ ├── init_files.luau
│ ├── invalid.luau
│ ├── module.luau
│ ├── modules/
│ │ ├── async.luau
│ │ ├── init.luau
│ │ ├── module.luau
│ │ ├── modules/
│ │ │ ├── init.luau
│ │ │ └── module.luau
│ │ ├── nested.luau
│ │ └── self_alias/
│ │ ├── init.luau
│ │ └── module.luau
│ ├── multi.ext.file.luau
│ ├── multi_ext.luau
│ ├── nested.luau
│ ├── parents.luau
│ ├── siblings.luau
│ ├── state.luau
│ ├── state_module.luau
│ └── state_second.luau
├── roblox/
│ ├── datatypes/
│ │ ├── Axes.luau
│ │ ├── BrickColor.luau
│ │ ├── CFrame.luau
│ │ ├── Color3.luau
│ │ ├── ColorSequence.luau
│ │ ├── ColorSequenceKeypoint.luau
│ │ ├── Content.luau
│ │ ├── Enum.luau
│ │ ├── Faces.luau
│ │ ├── Font.luau
│ │ ├── NumberRange.luau
│ │ ├── NumberSequence.luau
│ │ ├── NumberSequenceKeypoint.luau
│ │ ├── PhysicalProperties.luau
│ │ ├── Ray.luau
│ │ ├── Rect.luau
│ │ ├── Region3.luau
│ │ ├── Region3int16.luau
│ │ ├── UDim.luau
│ │ ├── UDim2.luau
│ │ ├── UniqueId.luau
│ │ ├── Vector2.luau
│ │ ├── Vector2int16.luau
│ │ ├── Vector3.luau
│ │ └── Vector3int16.luau
│ ├── files/
│ │ ├── deserializeModel.luau
│ │ ├── deserializePlace.luau
│ │ ├── serializeModel.luau
│ │ └── serializePlace.luau
│ ├── instance/
│ │ ├── attributes.luau
│ │ ├── classes/
│ │ │ ├── DataModel.luau
│ │ │ ├── Terrain.luau
│ │ │ └── Workspace.luau
│ │ ├── custom/
│ │ │ ├── async.luau
│ │ │ ├── methods.luau
│ │ │ └── properties.luau
│ │ ├── methods/
│ │ │ ├── ClearAllChildren.luau
│ │ │ ├── Clone.luau
│ │ │ ├── Destroy.luau
│ │ │ ├── FindFirstAncestor.luau
│ │ │ ├── FindFirstAncestorOfClass.luau
│ │ │ ├── FindFirstAncestorWhichIsA.luau
│ │ │ ├── FindFirstChild.luau
│ │ │ ├── FindFirstChildOfClass.luau
│ │ │ ├── FindFirstChildWhichIsA.luau
│ │ │ ├── GetChildren.luau
│ │ │ ├── GetDebugId.luau
│ │ │ ├── GetDescendants.luau
│ │ │ ├── GetFullName.luau
│ │ │ ├── IsA.luau
│ │ │ ├── IsAncestorOf.luau
│ │ │ └── IsDescendantOf.luau
│ │ ├── new.luau
│ │ ├── properties.luau
│ │ └── tags.luau
│ ├── misc/
│ │ └── typeof.luau
│ └── reflection/
│ ├── class.luau
│ ├── database.luau
│ ├── enums.luau
│ └── property.luau
├── serde/
│ ├── compression/
│ │ ├── files.luau
│ │ └── roundtrip.luau
│ ├── hashing/
│ │ ├── hash.luau
│ │ └── hmac.luau
│ ├── json/
│ │ ├── decode.luau
│ │ ├── encode.luau
│ │ └── source.luau
│ ├── jsonc/
│ │ ├── decode.luau
│ │ ├── encode.luau
│ │ └── source.luau
│ ├── test-files/
│ │ ├── loremipsum.txt
│ │ ├── loremipsum.txt.br
│ │ ├── loremipsum.txt.lz4
│ │ ├── loremipsum.txt.z
│ │ ├── loremipsum.txt.zst
│ │ ├── uncompressed.csv
│ │ ├── uncompressed.json
│ │ └── uncompressed.yaml
│ └── toml/
│ ├── decode.luau
│ ├── encode.luau
│ └── source.luau
├── stdio/
│ ├── color.luau
│ ├── ewrite.luau
│ ├── format.luau
│ ├── prompt.luau
│ ├── style.luau
│ └── write.luau
└── task/
├── cancel.luau
├── defer.luau
├── delay.luau
├── fcheck.luau
├── spawn.luau
└── wait.luau
SYMBOL INDEX (1478 symbols across 180 files)
FILE: crates/lune-roblox/src/datatypes/attributes.rs
function ensure_valid_attribute_name (line 16) | pub fn ensure_valid_attribute_name(name: impl AsRef<str>) -> LuaResult<(...
function ensure_valid_attribute_value (line 45) | pub fn ensure_valid_attribute_value(value: &DomValue) -> LuaResult<()> {
FILE: crates/lune-roblox/src/datatypes/conversion.rs
type LuaToDomValue (line 9) | pub(crate) trait LuaToDomValue {
method lua_to_dom_value (line 16) | fn lua_to_dom_value(
method lua_to_dom_value (line 80) | fn lua_to_dom_value(
method lua_to_dom_value (line 242) | fn lua_to_dom_value(&self, _: &Lua, variant_type: Option<DomType>) -> ...
type DomValueToLua (line 23) | pub(crate) trait DomValueToLua: Sized {
method dom_value_to_lua (line 27) | fn dom_value_to_lua(lua: &Lua, variant: &DomValue) -> DomConversionRes...
method dom_value_to_lua (line 41) | fn dom_value_to_lua(lua: &Lua, variant: &DomValue) -> DomConversionRes...
method dom_value_to_lua (line 192) | fn dom_value_to_lua(lua: &Lua, variant: &DomValue) -> DomConversionRes...
FILE: crates/lune-roblox/src/datatypes/extension.rs
type DomValueExt (line 3) | pub(crate) trait DomValueExt {
method variant_name (line 4) | fn variant_name(&self) -> Option<&'static str>;
method variant_name (line 8) | fn variant_name(&self) -> Option<&'static str> {
method variant_name (line 59) | fn variant_name(&self) -> Option<&'static str> {
FILE: crates/lune-roblox/src/datatypes/result.rs
type DomConversionError (line 11) | pub(crate) enum DomConversionError {
method fmt (line 30) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 67) | fn from(value: LuaError) -> Self {
method from (line 73) | fn from(value: IoError) -> Self {
method from (line 53) | fn from(value: DomConversionError) -> Self {
type DomConversionResult (line 80) | pub(crate) type DomConversionResult<T> = Result<T, DomConversionError>;
FILE: crates/lune-roblox/src/datatypes/types/axes.rs
type Axes (line 18) | pub struct Axes {
method fmt (line 98) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 108) | fn from(v: DomAxes) -> Self {
constant EXPORT_NAME (line 25) | const EXPORT_NAME: &'static str = "Axes";
method create_exports_table (line 27) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 79) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 91) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 119) | fn from(v: Axes) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/brick_color.rs
type BrickColor (line 19) | pub struct BrickColor {
method fmt (line 108) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 114) | fn from(value: Color3) -> Self {
method from (line 133) | fn from(v: DomBrickColor) -> Self {
method from (line 155) | fn from(value: BrickColorDef) -> Self {
constant EXPORT_NAME (line 28) | const EXPORT_NAME: &'static str = "BrickColor";
method create_exports_table (line 30) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 83) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 95) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method default (line 102) | fn default() -> Self {
method from (line 123) | fn from(value: BrickColor) -> Self {
method from (line 139) | fn from(v: BrickColor) -> Self {
type BrickColorDef (line 152) | type BrickColorDef = &'static (u16, &'static str, (u8, u8, u8));
constant BRICK_COLOR_DEFAULT_VALUE (line 164) | const BRICK_COLOR_DEFAULT_VALUE: BrickColorDef =
function color_from_number (line 167) | fn color_from_number(index: u16) -> BrickColor {
function color_from_name (line 175) | fn color_from_name(name: impl AsRef<str>) -> BrickColor {
function color_from_rgb (line 184) | fn color_from_rgb(r: u8, g: u8, b: u8) -> BrickColor {
constant BRICK_COLOR_DEFAULT (line 209) | const BRICK_COLOR_DEFAULT: u16 = 194;
constant BRICK_COLOR_VALUES (line 211) | const BRICK_COLOR_VALUES: &[(u16, &str, (u8, u8, u8))] = &[
constant BRICK_COLOR_PALETTE (line 422) | const BRICK_COLOR_PALETTE: &[u16] = &[
constant BRICK_COLOR_CONSTRUCTORS (line 432) | const BRICK_COLOR_CONSTRUCTORS: &[(&str, u16)] = &[
FILE: crates/lune-roblox/src/datatypes/types/cframe.rs
type CFrame (line 24) | pub struct CFrame(pub Mat4);
constant IDENTITY (line 27) | pub const IDENTITY: Self = Self(Mat4::IDENTITY);
method position (line 29) | fn position(&self) -> Vec3 {
method orientation (line 33) | fn orientation(&self) -> Mat3 {
method inverse (line 41) | fn inverse(&self) -> Self {
method fmt (line 349) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type Output (line 364) | type Output = Self;
method mul (line 365) | fn mul(self, rhs: Self) -> Self::Output {
type Output (line 371) | type Output = Vector3;
method mul (line 372) | fn mul(self, rhs: Vector3) -> Self::Output {
type Output (line 378) | type Output = Self;
method add (line 379) | fn add(self, rhs: Vector3) -> Self::Output {
type Output (line 390) | type Output = Self;
method sub (line 391) | fn sub(self, rhs: Vector3) -> Self::Output {
method from (line 402) | fn from(v: DomCFrame) -> Self {
constant EXPORT_NAME (line 47) | const EXPORT_NAME: &'static str = "CFrame";
method create_exports_table (line 50) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 178) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 204) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 414) | fn from(v: CFrame) -> Self {
function look_at (line 433) | fn look_at(from: Vec3, to: Vec3, up: Vec3) -> Mat4 {
function dom_cframe_from_cframe (line 454) | fn dom_cframe_from_cframe() {
function cframe_from_dom_cframe (line 475) | fn cframe_from_dom_cframe() {
FILE: crates/lune-roblox/src/datatypes/types/color3.rs
type Color3 (line 25) | pub struct Color3 {
method fmt (line 204) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type Output (line 210) | type Output = Self;
method neg (line 211) | fn neg(self) -> Self::Output {
type Output (line 221) | type Output = Self;
method add (line 222) | fn add(self, rhs: Self) -> Self::Output {
type Output (line 232) | type Output = Self;
method sub (line 233) | fn sub(self, rhs: Self) -> Self::Output {
type Output (line 243) | type Output = Color3;
method mul (line 244) | fn mul(self, rhs: Self) -> Self::Output {
type Output (line 254) | type Output = Color3;
method mul (line 255) | fn mul(self, rhs: f32) -> Self::Output {
type Output (line 265) | type Output = Color3;
method div (line 266) | fn div(self, rhs: Self) -> Self::Output {
type Output (line 276) | type Output = Color3;
method div (line 277) | fn div(self, rhs: f32) -> Self::Output {
method from (line 287) | fn from(v: DomColor3) -> Self {
method from (line 307) | fn from(v: DomColor3uint8) -> Self {
constant EXPORT_NAME (line 32) | const EXPORT_NAME: &'static str = "Color3";
method create_exports_table (line 34) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method from_lua (line 115) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
method add_fields (line 129) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 135) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method default (line 194) | fn default() -> Self {
method from (line 297) | fn from(v: Color3) -> Self {
method from (line 313) | fn from(v: Color3) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/color_sequence.rs
type ColorSequence (line 20) | pub struct ColorSequence {
method fmt (line 89) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 102) | fn from(v: DomColorSequence) -> Self {
constant EXPORT_NAME (line 25) | const EXPORT_NAME: &'static str = "ColorSequence";
method create_exports_table (line 27) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 78) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 82) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 115) | fn from(v: ColorSequence) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/color_sequence_keypoint.rs
type ColorSequenceKeypoint (line 18) | pub struct ColorSequenceKeypoint {
method fmt (line 54) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 60) | fn from(v: DomColorSequenceKeypoint) -> Self {
constant EXPORT_NAME (line 24) | const EXPORT_NAME: &'static str = "ColorSequenceKeypoint";
method create_exports_table (line 26) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 42) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 47) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 69) | fn from(v: ColorSequenceKeypoint) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/content.rs
type Content (line 18) | pub struct Content(ContentType);
method fmt (line 93) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
method from (line 108) | fn from(value: DomContent) -> Self {
constant EXPORT_NAME (line 21) | const EXPORT_NAME: &'static str = "Content";
method create_exports_table (line 23) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 53) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 86) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 114) | fn from(value: Content) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/enum.rs
type Enum (line 14) | pub struct Enum {
method from_name (line 19) | pub(crate) fn from_name(name: impl AsRef<str>) -> Option<Self> {
method fmt (line 56) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 68) | fn from(value: &'static EnumDescriptor<'static>) -> Self {
method add_methods (line 26) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method eq (line 62) | fn eq(&self, other: &Self) -> bool {
FILE: crates/lune-roblox/src/datatypes/types/enum_item.rs
type EnumItem (line 14) | pub struct EnumItem {
method from_enum_and_name (line 21) | pub(crate) fn from_enum_and_name(parent: &Enum, name: impl AsRef<str>)...
method from_enum_and_value (line 36) | pub(crate) fn from_enum_and_value(parent: &Enum, value: u32) -> Option...
method from_enum_name_and_name (line 50) | pub(crate) fn from_enum_name_and_name(
method from_enum_name_and_value (line 58) | pub(crate) fn from_enum_name_and_value(enum_name: impl AsRef<str>, val...
method fmt (line 92) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 113) | fn from(value: DomEnumItem) -> Self {
method add_fields (line 65) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 71) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from_lua (line 78) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
method eq (line 98) | fn eq(&self, other: &Self) -> bool {
method from (line 104) | fn from(v: EnumItem) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/enums.rs
type Enums (line 13) | pub struct Enums;
method fmt (line 38) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method add_methods (line 16) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
FILE: crates/lune-roblox/src/datatypes/types/faces.rs
type Faces (line 20) | pub struct Faces {
method fmt (line 106) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 119) | fn from(v: DomFaces) -> Self {
constant EXPORT_NAME (line 30) | const EXPORT_NAME: &'static str = "Faces";
method create_exports_table (line 32) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 90) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 99) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 133) | fn from(v: Faces) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/font.rs
type Font (line 21) | pub struct Font {
method from_enum_item (line 29) | pub(crate) fn from_enum_item(material_enum_item: &EnumItem) -> Option<...
method fmt (line 136) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 142) | fn from(v: DomFont) -> Self {
constant EXPORT_NAME (line 44) | const EXPORT_NAME: &'static str = "Font";
method create_exports_table (line 46) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 104) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 129) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 153) | fn from(v: Font) -> Self {
method from (line 170) | fn from(v: FontWeight) -> Self {
method from (line 182) | fn from(v: FontStyle) -> Self {
type FontData (line 195) | type FontData = (&'static str, FontWeight, FontStyle);
type FontWeight (line 198) | pub(crate) enum FontWeight {
method from (line 164) | fn from(v: DomFontWeight) -> Self {
method as_u16 (line 211) | pub(crate) fn as_u16(self) -> u16 {
method from_u16 (line 225) | pub(crate) fn from_u16(n: u16) -> Option<Self> {
type Err (line 248) | type Err = &'static str;
method from_str (line 249) | fn from_str(s: &str) -> Result<Self, Self::Err> {
method fmt (line 266) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
method default (line 242) | fn default() -> Self {
method from_lua (line 286) | fn from_lua(lua_value: LuaValue, _: &Lua) -> LuaResult<Self> {
method into_lua (line 314) | fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
type FontStyle (line 327) | pub(crate) enum FontStyle {
method from (line 176) | fn from(v: DomFontStyle) -> Self {
method as_u8 (line 333) | pub(crate) fn as_u8(self) -> u8 {
method from_u8 (line 340) | pub(crate) fn from_u8(n: u8) -> Option<Self> {
type Err (line 356) | type Err = &'static str;
method from_str (line 357) | fn from_str(s: &str) -> Result<Self, Self::Err> {
method fmt (line 367) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
method default (line 350) | fn default() -> Self {
method from_lua (line 380) | fn from_lua(lua_value: LuaValue, _: &Lua) -> LuaResult<Self> {
method into_lua (line 408) | fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
constant FONT_ENUM_MAP (line 421) | const FONT_ENUM_MAP: &[(&str, Option<FontData>)] = &[
FILE: crates/lune-roblox/src/datatypes/types/number_range.rs
type NumberRange (line 18) | pub struct NumberRange {
method fmt (line 56) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 62) | fn from(v: DomNumberRange) -> Self {
constant EXPORT_NAME (line 24) | const EXPORT_NAME: &'static str = "NumberRange";
method create_exports_table (line 26) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 44) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 49) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 71) | fn from(v: NumberRange) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/number_sequence.rs
type NumberSequence (line 20) | pub struct NumberSequence {
method fmt (line 93) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 106) | fn from(v: DomNumberSequence) -> Self {
constant EXPORT_NAME (line 25) | const EXPORT_NAME: &'static str = "NumberSequence";
method create_exports_table (line 27) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 82) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 86) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 119) | fn from(v: NumberSequence) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/number_sequence_keypoint.rs
type NumberSequenceKeypoint (line 18) | pub struct NumberSequenceKeypoint {
method fmt (line 57) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 63) | fn from(v: DomNumberSequenceKeypoint) -> Self {
constant EXPORT_NAME (line 25) | const EXPORT_NAME: &'static str = "NumberSequenceKeypoint";
method create_exports_table (line 27) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 44) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 50) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 73) | fn from(v: NumberSequenceKeypoint) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/physical_properties.rs
type PhysicalProperties (line 18) | pub struct PhysicalProperties {
method from_material (line 28) | pub(crate) fn from_material(material_enum_item: &EnumItem) -> Option<P...
method fmt (line 114) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 128) | fn from(v: DomCustomPhysicalProperties) -> Self {
constant EXPORT_NAME (line 44) | const EXPORT_NAME: &'static str = "PhysicalProperties";
method create_exports_table (line 46) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 98) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 107) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 141) | fn from(v: PhysicalProperties) -> Self {
constant MATERIAL_ENUM_MAP (line 161) | const MATERIAL_ENUM_MAP: &[(&str, f32, f32, f32, f32, f32, f32)] = &[
FILE: crates/lune-roblox/src/datatypes/types/ray.rs
type Ray (line 20) | pub struct Ray {
method closest_point (line 26) | fn closest_point(&self, point: Vec3) -> Vec3 {
method fmt (line 81) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 87) | fn from(v: DomRay) -> Self {
constant EXPORT_NAME (line 36) | const EXPORT_NAME: &'static str = "Ray";
method create_exports_table (line 38) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 54) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 65) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 96) | fn from(v: Ray) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/rect.rs
type Rect (line 21) | pub struct Rect {
method new (line 27) | fn new(lhs: Vec2, rhs: Vec2) -> Self {
method fmt (line 87) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type Output (line 93) | type Output = Self;
method neg (line 94) | fn neg(self) -> Self::Output {
type Output (line 100) | type Output = Self;
method add (line 101) | fn add(self, rhs: Self) -> Self::Output {
type Output (line 107) | type Output = Self;
method sub (line 108) | fn sub(self, rhs: Self) -> Self::Output {
method from (line 114) | fn from(v: DomRect) -> Self {
constant EXPORT_NAME (line 36) | const EXPORT_NAME: &'static str = "Rect";
method create_exports_table (line 38) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 70) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 77) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 123) | fn from(v: Rect) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/region3.rs
type Region3 (line 20) | pub struct Region3 {
method fmt (line 66) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 72) | fn from(v: DomRegion3) -> Self {
constant EXPORT_NAME (line 26) | const EXPORT_NAME: &'static str = "Region3";
method create_exports_table (line 28) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 44) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 51) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 81) | fn from(v: Region3) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/region3int16.rs
type Region3int16 (line 20) | pub struct Region3int16 {
method fmt (line 56) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 62) | fn from(v: DomRegion3int16) -> Self {
constant EXPORT_NAME (line 26) | const EXPORT_NAME: &'static str = "Region3int16";
method create_exports_table (line 28) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 44) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 49) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 71) | fn from(v: Region3int16) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/udim.rs
type UDim (line 19) | pub struct UDim {
method new (line 25) | pub(super) fn new(scale: f32, offset: i32) -> Self {
method fmt (line 72) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type Output (line 78) | type Output = Self;
method neg (line 79) | fn neg(self) -> Self::Output {
type Output (line 88) | type Output = Self;
method add (line 89) | fn add(self, rhs: Self) -> Self::Output {
type Output (line 98) | type Output = Self;
method sub (line 99) | fn sub(self, rhs: Self) -> Self::Output {
method from (line 108) | fn from(v: DomUDim) -> Self {
constant EXPORT_NAME (line 31) | const EXPORT_NAME: &'static str = "UDim";
method create_exports_table (line 33) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 48) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 53) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method default (line 63) | fn default() -> Self {
method from (line 117) | fn from(v: UDim) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/udim2.rs
type UDim2 (line 22) | pub struct UDim2 {
method fmt (line 118) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type Output (line 124) | type Output = Self;
method neg (line 125) | fn neg(self) -> Self::Output {
type Output (line 134) | type Output = Self;
method add (line 135) | fn add(self, rhs: Self) -> Self::Output {
type Output (line 144) | type Output = Self;
method sub (line 145) | fn sub(self, rhs: Self) -> Self::Output {
method from (line 154) | fn from(v: DomUDim2) -> Self {
constant EXPORT_NAME (line 28) | const EXPORT_NAME: &'static str = "UDim2";
method create_exports_table (line 30) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 75) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 82) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 163) | fn from(v: UDim2) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/unique_id.rs
type UniqueId (line 20) | pub struct UniqueId {
method fmt (line 66) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 75) | fn from(value: DomUniqueId) -> Self {
constant EXPORT_NAME (line 25) | const EXPORT_NAME: &'static str = "UniqueId";
method create_exports_table (line 27) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_methods (line 59) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 87) | fn from(value: UniqueId) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/vector2.rs
type Vector2 (line 22) | pub struct Vector2(pub Vec2);
method fmt (line 103) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type Output (line 109) | type Output = Self;
method neg (line 110) | fn neg(self) -> Self::Output {
type Output (line 116) | type Output = Self;
method add (line 117) | fn add(self, rhs: Self) -> Self::Output {
type Output (line 123) | type Output = Self;
method sub (line 124) | fn sub(self, rhs: Self) -> Self::Output {
type Output (line 130) | type Output = Vector2;
method mul (line 131) | fn mul(self, rhs: Self) -> Self::Output {
type Output (line 137) | type Output = Vector2;
method mul (line 138) | fn mul(self, rhs: f32) -> Self::Output {
type Output (line 144) | type Output = Vector2;
method div (line 145) | fn div(self, rhs: Self) -> Self::Output {
type Output (line 151) | type Output = Vector2;
method div (line 152) | fn div(self, rhs: f32) -> Self::Output {
type Output (line 165) | type Output = Vector2;
method idiv (line 166) | fn idiv(self, rhs: f32) -> Self::Output {
method from (line 172) | fn from(v: DomVector2) -> Self {
constant EXPORT_NAME (line 25) | const EXPORT_NAME: &'static str = "Vector2";
method create_exports_table (line 27) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 46) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 53) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
type Output (line 158) | type Output = Vector2;
method idiv (line 159) | fn idiv(self, rhs: Self) -> Self::Output {
method from (line 178) | fn from(v: Vector2) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/vector2int16.rs
type Vector2int16 (line 22) | pub struct Vector2int16(pub IVec2);
method fmt (line 59) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type Output (line 65) | type Output = Self;
method neg (line 66) | fn neg(self) -> Self::Output {
type Output (line 72) | type Output = Self;
method add (line 73) | fn add(self, rhs: Self) -> Self::Output {
type Output (line 79) | type Output = Self;
method sub (line 80) | fn sub(self, rhs: Self) -> Self::Output {
type Output (line 86) | type Output = Vector2int16;
method mul (line 87) | fn mul(self, rhs: Self) -> Self::Output {
type Output (line 93) | type Output = Vector2int16;
method mul (line 94) | fn mul(self, rhs: i32) -> Self::Output {
type Output (line 100) | type Output = Vector2int16;
method div (line 101) | fn div(self, rhs: Self) -> Self::Output {
type Output (line 107) | type Output = Vector2int16;
method div (line 108) | fn div(self, rhs: i32) -> Self::Output {
method from (line 114) | fn from(v: DomVector2int16) -> Self {
constant EXPORT_NAME (line 25) | const EXPORT_NAME: &'static str = "Vector2int16";
method create_exports_table (line 27) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 42) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 47) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 123) | fn from(v: Vector2int16) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/vector3.rs
type Vector3 (line 25) | pub struct Vector3(pub Vec3);
method fmt (line 153) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type Output (line 159) | type Output = Self;
method neg (line 160) | fn neg(self) -> Self::Output {
type Output (line 166) | type Output = Self;
method add (line 167) | fn add(self, rhs: Self) -> Self::Output {
type Output (line 173) | type Output = Self;
method sub (line 174) | fn sub(self, rhs: Self) -> Self::Output {
type Output (line 180) | type Output = Vector3;
method mul (line 181) | fn mul(self, rhs: Self) -> Self::Output {
type Output (line 187) | type Output = Vector3;
method mul (line 188) | fn mul(self, rhs: f32) -> Self::Output {
type Output (line 194) | type Output = Vector3;
method div (line 195) | fn div(self, rhs: Self) -> Self::Output {
type Output (line 201) | type Output = Vector3;
method div (line 202) | fn div(self, rhs: f32) -> Self::Output {
type Output (line 215) | type Output = Vector3;
method idiv (line 216) | fn idiv(self, rhs: f32) -> Self::Output {
method from (line 222) | fn from(v: DomVector3) -> Self {
constant EXPORT_NAME (line 28) | const EXPORT_NAME: &'static str = "Vector3";
method create_exports_table (line 30) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 96) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 104) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
type Output (line 208) | type Output = Vector3;
method idiv (line 209) | fn idiv(self, rhs: Self) -> Self::Output {
method from (line 232) | fn from(v: Vector3) -> Self {
FILE: crates/lune-roblox/src/datatypes/types/vector3int16.rs
type Vector3int16 (line 22) | pub struct Vector3int16(pub IVec3);
method fmt (line 61) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type Output (line 67) | type Output = Self;
method neg (line 68) | fn neg(self) -> Self::Output {
type Output (line 74) | type Output = Self;
method add (line 75) | fn add(self, rhs: Self) -> Self::Output {
type Output (line 81) | type Output = Self;
method sub (line 82) | fn sub(self, rhs: Self) -> Self::Output {
type Output (line 88) | type Output = Vector3int16;
method mul (line 89) | fn mul(self, rhs: Self) -> Self::Output {
type Output (line 95) | type Output = Vector3int16;
method mul (line 96) | fn mul(self, rhs: i32) -> Self::Output {
type Output (line 102) | type Output = Vector3int16;
method div (line 103) | fn div(self, rhs: Self) -> Self::Output {
type Output (line 109) | type Output = Vector3int16;
method div (line 110) | fn div(self, rhs: i32) -> Self::Output {
method from (line 116) | fn from(v: DomVector3int16) -> Self {
constant EXPORT_NAME (line 25) | const EXPORT_NAME: &'static str = "Vector3int16";
method create_exports_table (line 27) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 43) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 49) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method from (line 126) | fn from(v: Vector3int16) -> Self {
FILE: crates/lune-roblox/src/datatypes/util.rs
constant ROUNDING (line 4) | const ROUNDING: usize = 65_536;
function round_float_decimal (line 6) | pub fn round_float_decimal(value: f32) -> f32 {
FILE: crates/lune-roblox/src/document/error.rs
type DocumentError (line 7) | pub enum DocumentError {
method from (line 28) | fn from(value: DocumentError) -> Self {
FILE: crates/lune-roblox/src/document/format.rs
type DocumentFormat (line 17) | pub enum DocumentFormat {
method from_extension (line 28) | pub fn from_extension(extension: impl AsRef<str>) -> Option<Self> {
method from_path (line 42) | pub fn from_path(path: impl AsRef<Path>) -> Option<Self> {
method from_bytes (line 60) | pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Option<Self> {
method default (line 76) | fn default() -> Self {
function from_extension_binary (line 88) | fn from_extension_binary() {
function from_extension_xml (line 101) | fn from_extension_xml() {
function from_extension_invalid (line 114) | fn from_extension_invalid() {
function from_path_binary (line 124) | fn from_path_binary() {
function from_path_xml (line 137) | fn from_path_xml() {
function from_path_invalid (line 150) | fn from_path_invalid() {
function from_bytes_binary (line 170) | fn from_bytes_binary() {
function from_bytes_xml (line 183) | fn from_bytes_xml() {
function from_bytes_invalid (line 196) | fn from_bytes_invalid() {
FILE: crates/lune-roblox/src/document/kind.rs
type DocumentKind (line 18) | pub enum DocumentKind {
method from_extension (line 29) | pub fn from_extension(extension: impl AsRef<str>) -> Option<Self> {
method from_path (line 43) | pub fn from_path(path: impl AsRef<Path>) -> Option<Self> {
method from_weak_dom (line 62) | pub fn from_weak_dom(dom: &WeakDom) -> Option<Self> {
function from_extension_place (line 93) | fn from_extension_place() {
function from_extension_model (line 106) | fn from_extension_model() {
function from_extension_invalid (line 119) | fn from_extension_invalid() {
function from_path_place (line 129) | fn from_path_place() {
function from_path_model (line 142) | fn from_path_model() {
function from_path_invalid (line 155) | fn from_path_invalid() {
function from_weak_dom (line 175) | fn from_weak_dom() {
FILE: crates/lune-roblox/src/document/mod.rs
type DocumentResult (line 20) | pub type DocumentResult<T> = Result<T, DocumentError>;
type Document (line 63) | pub struct Document {
method canonical_extension (line 83) | pub fn canonical_extension(kind: DocumentKind, format: DocumentFormat)...
method from_bytes_inner (line 92) | fn from_bytes_inner(bytes: impl AsRef<[u8]>) -> DocumentResult<(Docume...
method from_bytes_auto (line 122) | pub fn from_bytes_auto(bytes: impl AsRef<[u8]>) -> DocumentResult<Self> {
method from_bytes (line 138) | pub fn from_bytes(bytes: impl AsRef<[u8]>, kind: DocumentKind) -> Docu...
method to_bytes (line 155) | pub fn to_bytes(&self) -> DocumentResult<Vec<u8>> {
method to_bytes_with_format (line 167) | pub fn to_bytes_with_format(&self, format: DocumentFormat) -> Document...
method kind (line 193) | pub fn kind(&self) -> DocumentKind {
method format (line 201) | pub fn format(&self) -> DocumentFormat {
method extension (line 209) | pub fn extension(&self) -> &'static str {
method into_data_model_instance (line 220) | pub fn into_data_model_instance(mut self) -> DocumentResult<Instance> {
method into_instance_array (line 248) | pub fn into_instance_array(mut self) -> DocumentResult<Vec<Instance>> {
method from_data_model_instance (line 270) | pub fn from_data_model_instance(i: Instance) -> DocumentResult<Self> {
method from_instance_array (line 299) | pub fn from_instance_array(v: Vec<Instance>) -> DocumentResult<Self> {
FILE: crates/lune-roblox/src/document/postprocessing.rs
function postprocess_dom_for_place (line 9) | pub fn postprocess_dom_for_place(_dom: &mut WeakDom) {
function postprocess_dom_for_model (line 13) | pub fn postprocess_dom_for_model(dom: &mut WeakDom) {
function recurse_instances (line 28) | fn recurse_instances<F>(dom: &mut WeakDom, dom_ref: DomRef, f: &F)
function remove_matching_prop (line 44) | fn remove_matching_prop(inst: &mut DomInstance, ty: DomType, name: &'sta...
FILE: crates/lune-roblox/src/exports.rs
type LuaExportsTable (line 40) | pub trait LuaExportsTable {
constant EXPORT_NAME (line 41) | const EXPORT_NAME: &'static str;
method create_exports_table (line 43) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable>;
function export (line 60) | pub fn export<T>(lua: Lua) -> LuaResult<(&'static str, LuaValue)>
FILE: crates/lune-roblox/src/instance/base.rs
function add_methods (line 23) | pub fn add_methods<M: LuaUserDataMethods<Instance>>(m: &mut M) {
function ensure_not_destroyed (line 192) | fn ensure_not_destroyed(inst: &Instance) -> LuaResult<()> {
function instance_property_get (line 214) | fn instance_property_get(lua: &Lua, this: &Instance, prop_name: String) ...
function instance_property_set (line 294) | fn instance_property_set(
FILE: crates/lune-roblox/src/instance/data_model.rs
constant CLASS_NAME (line 13) | pub const CLASS_NAME: &str = "DataModel";
function add_fields (line 15) | pub fn add_fields<F: LuaUserDataFields<Instance>>(f: &mut F) {
function add_methods (line 19) | pub fn add_methods<M: LuaUserDataMethods<Instance>>(m: &mut M) {
function data_model_get_workspace (line 31) | fn data_model_get_workspace(_: &Lua, this: &Instance) -> LuaResult<Insta...
function data_model_get_service (line 42) | fn data_model_get_service(_: &Lua, this: &Instance, service_name: String...
function data_model_find_service (line 63) | fn data_model_find_service(
FILE: crates/lune-roblox/src/instance/mod.rs
constant PROPERTY_NAME_ATTRIBUTES (line 39) | const PROPERTY_NAME_ATTRIBUTES: &str = "Attributes";
constant PROPERTY_NAME_TAGS (line 40) | const PROPERTY_NAME_TAGS: &str = "Tags";
type Instance (line 46) | pub struct Instance {
method new (line 62) | pub fn new(dom_ref: DomRef) -> Self {
method new_opt (line 75) | pub fn new_opt(dom_ref: DomRef) -> Option<Self> {
method new_orphaned (line 102) | pub fn new_orphaned(class_name: impl AsRef<str>) -> Self {
method from_external_dom (line 127) | pub fn from_external_dom(external_dom: &mut WeakDom, external_dom_ref:...
method clone_into_external_dom (line 143) | pub fn clone_into_external_dom(self, external_dom: &mut WeakDom) -> Do...
method clone_multiple_into_external_dom (line 158) | pub fn clone_multiple_into_external_dom(
method clone_instance (line 184) | pub fn clone_instance(&self) -> Self {
method destroy (line 207) | pub fn destroy(&mut self) -> bool {
method is_destroyed (line 218) | fn is_destroyed(&self) -> bool {
method clear_all_children (line 234) | pub fn clear_all_children(&mut self) {
method is_a (line 254) | pub fn is_a(&self, class_name: impl AsRef<str>) -> bool {
method get_class_name (line 268) | pub fn get_class_name(&self) -> &str {
method get_name (line 279) | pub fn get_name(&self) -> String {
method set_name (line 295) | pub fn set_name(&self, name: impl Into<String>) {
method get_parent (line 310) | pub fn get_parent(&self) -> Option<Instance> {
method set_parent (line 334) | pub fn set_parent(&self, parent: Option<Instance>) {
method get_property (line 345) | pub fn get_property(&self, name: impl AsRef<str>) -> Option<DomValue> {
method set_property (line 362) | pub fn set_property(&self, name: impl AsRef<str>, value: DomValue) {
method get_attribute (line 379) | pub fn get_attribute(&self, name: impl AsRef<str>) -> Option<DomValue> {
method get_attributes (line 400) | pub fn get_attributes(&self) -> BTreeMap<String, DomValue> {
method set_attribute (line 421) | pub fn set_attribute(&self, name: impl AsRef<str>, value: DomValue) {
method remove_attribute (line 454) | pub fn remove_attribute(&self, name: impl AsRef<str>) {
method add_tag (line 476) | pub fn add_tag(&self, name: impl AsRef<str>) {
method get_tags (line 498) | pub fn get_tags(&self) -> Vec<String> {
method has_tag (line 517) | pub fn has_tag(&self, name: impl AsRef<str>) -> bool {
method remove_tag (line 537) | pub fn remove_tag(&self, name: impl AsRef<str>) {
method get_children (line 561) | pub fn get_children(&self) -> Vec<Instance> {
method get_descendants (line 584) | pub fn get_descendants(&self) -> Vec<Instance> {
method get_full_name (line 618) | pub fn get_full_name(&self) -> String {
method find_child (line 646) | pub fn find_child<F>(&self, predicate: F) -> Option<Instance>
method find_ancestor (line 678) | pub fn find_ancestor<F>(&self, predicate: F) -> Option<Instance>
method find_descendant (line 707) | pub fn find_descendant<F>(&self, predicate: F) -> Option<Instance>
method fmt (line 789) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
constant EXPORT_NAME (line 737) | const EXPORT_NAME: &'static str = "Instance";
method create_exports_table (line 739) | fn create_exports_table(lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 770) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 775) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method hash (line 783) | fn hash<H: Hasher>(&self, state: &mut H) {
method eq (line 803) | fn eq(&self, other: &Self) -> bool {
method from (line 809) | fn from(value: Instance) -> Self {
FILE: crates/lune-roblox/src/instance/registry.rs
type InstanceRegistryMap (line 12) | type InstanceRegistryMap = HashMap<String, HashMap<String, LuaRegistryKe...
type InstanceRegistryError (line 15) | pub enum InstanceRegistryError {
type InstanceRegistry (line 31) | pub struct InstanceRegistry {
method get_or_create (line 42) | fn get_or_create(lua: &Lua) -> AppDataRef<'_, Self> {
method insert_method (line 61) | pub fn insert_method(
method insert_property_getter (line 97) | pub fn insert_property_getter(
method insert_property_setter (line 133) | pub fn insert_property_setter(
method find_method (line 168) | pub fn find_method(lua: &Lua, instance: &Instance, method_name: &str) ...
method find_property_getter (line 191) | pub fn find_property_getter(
method find_property_setter (line 218) | pub fn find_property_setter(
function class_name_chain (line 250) | pub fn class_name_chain(class_name: &str) -> Vec<&str> {
FILE: crates/lune-roblox/src/instance/terrain.rs
constant CLASS_NAME (line 11) | pub const CLASS_NAME: &str = "Terrain";
function add_methods (line 13) | pub fn add_methods<M: LuaUserDataMethods<Instance>>(methods: &mut M) {
function get_or_create_material_colors (line 29) | fn get_or_create_material_colors(instance: &Instance) -> MaterialColors {
function terrain_get_material_color (line 44) | fn terrain_get_material_color(_: &Lua, this: &Instance, material: EnumIt...
function terrain_set_material_color (line 69) | fn terrain_set_material_color(
FILE: crates/lune-roblox/src/instance/workspace.rs
constant CLASS_NAME (line 7) | pub const CLASS_NAME: &str = "Workspace";
function add_fields (line 9) | pub fn add_fields<F: LuaUserDataFields<Instance>>(f: &mut F) {
function workspace_get_terrain (line 21) | fn workspace_get_terrain(_: &Lua, this: &Instance) -> LuaResult<Instance> {
function workspace_get_camera (line 32) | fn workspace_get_camera(_: &Lua, this: &Instance) -> LuaResult<Instance> {
FILE: crates/lune-roblox/src/lib.rs
function create_all_exports (line 22) | fn create_all_exports(lua: Lua) -> LuaResult<Vec<(&'static str, LuaValue...
function module (line 69) | pub fn module(lua: Lua) -> LuaResult<LuaTable> {
FILE: crates/lune-roblox/src/reflection/class.rs
type DbClass (line 20) | type DbClass = &'static ClassDescriptor<'static>;
type DatabaseClass (line 27) | pub struct DatabaseClass(DbClass);
method new (line 30) | pub(crate) fn new(inner: DbClass) -> Self {
method get_name (line 38) | pub fn get_name(&self) -> String {
method get_superclass (line 48) | pub fn get_superclass(&self) -> Option<String> {
method get_properties (line 57) | pub fn get_properties(&self) -> HashMap<String, DatabaseProperty> {
method get_defaults (line 69) | pub fn get_defaults(&self) -> HashMap<String, DomVariant> {
method get_tags_str (line 83) | pub fn get_tags_str(&self) -> Vec<&'static str> {
method fmt (line 131) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method add_fields (line 95) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 118) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method eq (line 125) | fn eq(&self, other: &Self) -> bool {
function find_enum_name (line 137) | fn find_enum_name(inner: DbClass, name: impl AsRef<str>) -> Option<Strin...
function make_enum_value (line 152) | fn make_enum_value(inner: DbClass, name: impl AsRef<str>, value: u32) ->...
FILE: crates/lune-roblox/src/reflection/enums.rs
type DbEnum (line 11) | type DbEnum = &'static EnumDescriptor<'static>;
type DatabaseEnum (line 18) | pub struct DatabaseEnum(DbEnum);
method new (line 21) | pub(crate) fn new(inner: DbEnum) -> Self {
method get_name (line 29) | pub fn get_name(&self) -> String {
method get_items (line 40) | pub fn get_items(&self) -> HashMap<String, u32> {
method fmt (line 69) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method add_fields (line 51) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 56) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method eq (line 63) | fn eq(&self, other: &Self) -> bool {
FILE: crates/lune-roblox/src/reflection/mod.rs
type Db (line 20) | type Db = &'static ReflectionDatabase<'static>;
type Database (line 27) | pub struct Database(Db);
method new (line 34) | pub fn new() -> Self {
method get_version (line 45) | pub fn get_version(&self) -> String {
method get_enum_names (line 54) | pub fn get_enum_names(&self) -> Vec<String> {
method get_class_names (line 62) | pub fn get_class_names(&self) -> Vec<String> {
method get_enum (line 69) | pub fn get_enum(&self, name: impl AsRef<str>) -> Option<DatabaseEnum> {
method get_class (line 77) | pub fn get_class(&self, name: impl AsRef<str>) -> Option<DatabaseClass> {
method find_enum (line 87) | pub fn find_enum(&self, name: impl AsRef<str>) -> Option<DatabaseEnum> {
method find_class (line 102) | pub fn find_class(&self, name: impl AsRef<str>) -> Option<DatabaseClas...
method fmt (line 149) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method add_fields (line 115) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 119) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method default (line 137) | fn default() -> Self {
method eq (line 143) | fn eq(&self, _other: &Self) -> bool {
FILE: crates/lune-roblox/src/reflection/property.rs
type DbClass (line 13) | type DbClass = &'static ClassDescriptor<'static>;
type DbProp (line 14) | type DbProp = &'static PropertyDescriptor<'static>;
type DatabaseProperty (line 21) | pub struct DatabaseProperty(DbClass, DbProp);
method new (line 24) | pub(crate) fn new(inner: DbClass, inner_prop: DbProp) -> Self {
method get_name (line 32) | pub fn get_name(&self) -> String {
method get_datatype_name (line 44) | pub fn get_datatype_name(&self) -> String {
method get_scriptability_str (line 54) | pub fn get_scriptability_str(&self) -> &'static str {
method get_tags_str (line 64) | pub fn get_tags_str(&self) -> Vec<&'static str> {
method fmt (line 96) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method add_fields (line 76) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 83) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method eq (line 90) | fn eq(&self, other: &Self) -> bool {
FILE: crates/lune-roblox/src/reflection/utils.rs
function data_type_to_str (line 5) | pub fn data_type_to_str(data_type: DataType) -> String {
function scriptability_to_str (line 20) | pub fn scriptability_to_str(scriptability: Scriptability) -> &'static str {
function property_tag_to_str (line 31) | pub fn property_tag_to_str(tag: PropertyTag) -> &'static str {
function class_tag_to_str (line 44) | pub fn class_tag_to_str(tag: ClassTag) -> &'static str {
FILE: crates/lune-roblox/src/shared/classes.rs
function add_class_restricted_getter (line 9) | pub(crate) fn add_class_restricted_getter<F: LuaUserDataFields<Instance>...
function add_class_restricted_setter (line 30) | pub(crate) fn add_class_restricted_setter<F: LuaUserDataFields<Instance>...
function add_class_restricted_method (line 50) | pub(crate) fn add_class_restricted_method<M: LuaUserDataMethods<Instance...
function add_class_restricted_method_mut (line 71) | pub(crate) fn add_class_restricted_method_mut<M: LuaUserDataMethods<Inst...
function get_or_create_property_ref_instance (line 104) | pub(crate) fn get_or_create_property_ref_instance(
FILE: crates/lune-roblox/src/shared/instance.rs
type PropertyInfo (line 9) | pub(crate) struct PropertyInfo {
function find_property_info (line 24) | pub(crate) fn find_property_info(
function class_exists (line 105) | pub fn class_exists(class_name: impl AsRef<str>) -> bool {
function class_is_a (line 118) | pub fn class_is_a(instance_class: impl AsRef<str>, class_name: impl AsRe...
function class_is_a_service (line 149) | pub fn class_is_a_service(instance_class: impl AsRef<str>) -> Option<boo...
function is_a_class_valid (line 173) | fn is_a_class_valid() {
function is_a_class_invalid (line 185) | fn is_a_class_invalid() {
function is_a_service_valid (line 197) | fn is_a_service_valid() {
function is_a_service_invalid (line 205) | fn is_a_service_invalid() {
FILE: crates/lune-roblox/src/shared/userdata.rs
type ListWriter (line 9) | type ListWriter = dyn Fn(&mut fmt::Formatter<'_>, bool, &str) -> fmt::Re...
function make_list_writer (line 12) | pub fn make_list_writer() -> Box<ListWriter> {
function userdata_impl_to_string (line 34) | pub fn userdata_impl_to_string<D>(_: &Lua, datatype: &D, _: ()) -> LuaRe...
function userdata_impl_eq (line 41) | pub fn userdata_impl_eq<D>(_: &Lua, datatype: &D, value: LuaValue) -> Lu...
function userdata_impl_unm (line 56) | pub fn userdata_impl_unm<D>(_: &Lua, datatype: &D, _: ()) -> LuaResult<D>
function userdata_impl_add (line 63) | pub fn userdata_impl_add<D>(_: &Lua, datatype: &D, value: LuaUserDataRef...
function userdata_impl_sub (line 70) | pub fn userdata_impl_sub<D>(_: &Lua, datatype: &D, value: LuaUserDataRef...
function userdata_impl_mul_f32 (line 77) | pub fn userdata_impl_mul_f32<D>(_: &Lua, datatype: &D, rhs: LuaValue) ->...
function userdata_impl_mul_i32 (line 102) | pub fn userdata_impl_mul_i32<D>(_: &Lua, datatype: &D, rhs: LuaValue) ->...
function userdata_impl_div_f32 (line 127) | pub fn userdata_impl_div_f32<D>(_: &Lua, datatype: &D, rhs: LuaValue) ->...
type IDiv (line 152) | pub trait IDiv<Rhs = Self> {
method idiv (line 155) | fn idiv(self, rhs: Rhs) -> Self::Output;
function userdata_impl_idiv_f32 (line 158) | pub fn userdata_impl_idiv_f32<D>(_: &Lua, datatype: &D, rhs: LuaValue) -...
function userdata_impl_div_i32 (line 183) | pub fn userdata_impl_div_i32<D>(_: &Lua, datatype: &D, rhs: LuaValue) ->...
FILE: crates/lune-std-datetime/src/date_time.rs
constant DEFAULT_FORMAT (line 12) | const DEFAULT_FORMAT: &str = "%Y-%m-%d %H:%M:%S";
constant DEFAULT_LOCALE (line 13) | const DEFAULT_LOCALE: &str = "en";
type DateTime (line 16) | pub struct DateTime {
method now (line 30) | pub fn now() -> Self {
method from_unix_timestamp_float (line 52) | pub fn from_unix_timestamp_float(unix_timestamp: f64) -> DateTimeResul...
method from_universal_time (line 74) | pub fn from_universal_time(values: &DateTimeValues) -> DateTimeResult<...
method from_local_time (line 102) | pub fn from_local_time(values: &DateTimeValues) -> DateTimeResult<Self> {
method format_string_local (line 132) | pub fn format_string_local(&self, format: Option<&str>, locale: Option...
method format_string_universal (line 151) | pub fn format_string_universal(&self, format: Option<&str>, locale: Op...
method from_rfc_3339 (line 171) | pub fn from_rfc_3339(date: impl AsRef<str>) -> DateTimeResult<Self> {
method from_rfc_2822 (line 186) | pub fn from_rfc_2822(date: impl AsRef<str>) -> DateTimeResult<Self> {
method to_local_time (line 196) | pub fn to_local_time(self) -> DateTimeValues {
method to_universal_time (line 205) | pub fn to_universal_time(self) -> DateTimeValues {
method to_rfc_3339 (line 215) | pub fn to_rfc_3339(self) -> String {
method to_rfc_2822 (line 225) | pub fn to_rfc_2822(self) -> String {
method add_fields (line 231) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 238) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
FILE: crates/lune-std-datetime/src/lib.rs
constant TYPEDEFS (line 13) | const TYPEDEFS: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), ...
function typedefs (line 19) | pub fn typedefs() -> String {
function module (line 30) | pub fn module(lua: Lua) -> LuaResult<LuaTable> {
FILE: crates/lune-std-datetime/src/result.rs
type DateTimeResult (line 5) | pub type DateTimeResult<T, E = DateTimeError> = Result<T, E>;
type DateTimeError (line 8) | pub enum DateTimeError {
method from (line 29) | fn from(value: DateTimeError) -> Self {
FILE: crates/lune-std-datetime/src/values.rs
type DateTimeValues (line 10) | pub struct DateTimeValues {
method verify (line 34) | pub fn verify(self) -> DateTimeResult<Self> {
method from (line 126) | fn from(value: DateTime<T>) -> Self {
function verify_in_range (line 46) | fn verify_in_range<T>(name: &'static str, value: T, min: T, max: T) -> D...
method from_lua (line 72) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
method into_lua (line 104) | fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
type Error (line 140) | type Error = DateTimeError;
function try_from (line 141) | fn try_from(value: DateTimeValues) -> Result<Self, Self::Error> {
type Error (line 156) | type Error = DateTimeError;
function try_from (line 157) | fn try_from(value: DateTimeValues) -> Result<Self, Self::Error> {
FILE: crates/lune-std-fs/src/copy.rs
type CopyContents (line 11) | pub struct CopyContents {
function get_contents_at (line 17) | async fn get_contents_at(root: PathBuf, _: FsWriteOptions) -> LuaResult<...
function ensure_no_dir_exists (line 73) | async fn ensure_no_dir_exists(path: impl AsRef<Path>) -> LuaResult<()> {
function ensure_no_file_exists (line 84) | async fn ensure_no_file_exists(path: impl AsRef<Path>) -> LuaResult<()> {
function copy (line 95) | pub async fn copy(
FILE: crates/lune-std-fs/src/lib.rs
constant TYPEDEFS (line 21) | const TYPEDEFS: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), ...
function typedefs (line 27) | pub fn typedefs() -> String {
function module (line 38) | pub fn module(lua: Lua) -> LuaResult<LuaTable> {
function fs_read_file (line 54) | async fn fs_read_file(lua: Lua, path: String) -> LuaResult<LuaString> {
function fs_read_dir (line 60) | async fn fs_read_dir(_: Lua, path: String) -> LuaResult<Vec<String>> {
function fs_write_file (line 76) | async fn fs_write_file(_: Lua, (path, contents): (String, BString)) -> L...
function fs_write_dir (line 80) | async fn fs_write_dir(_: Lua, path: String) -> LuaResult<()> {
function fs_remove_file (line 84) | async fn fs_remove_file(_: Lua, path: String) -> LuaResult<()> {
function fs_remove_dir (line 88) | async fn fs_remove_dir(_: Lua, path: String) -> LuaResult<()> {
function fs_metadata (line 92) | async fn fs_metadata(_: Lua, path: String) -> LuaResult<FsMetadata> {
function fs_is_file (line 100) | async fn fs_is_file(_: Lua, path: String) -> LuaResult<bool> {
function fs_is_dir (line 108) | async fn fs_is_dir(_: Lua, path: String) -> LuaResult<bool> {
function fs_move (line 116) | async fn fs_move(_: Lua, (from, to, options): (String, String, FsWriteOp...
function fs_copy (line 135) | async fn fs_copy(_: Lua, (from, to, options): (String, String, FsWriteOp...
FILE: crates/lune-std-fs/src/metadata.rs
type FsMetadataKind (line 14) | pub enum FsMetadataKind {
method fmt (line 22) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 51) | fn from(value: StdFileType) -> Self {
type Err (line 37) | type Err = &'static str;
method from_str (line 39) | fn from_str(s: &str) -> Result<Self, Self::Err> {
method into_lua (line 65) | fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
type FsPermissions (line 75) | pub struct FsPermissions {
method from (line 80) | fn from(value: StdPermissions) -> Self {
method into_lua (line 88) | fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
type FsMetadata (line 97) | pub struct FsMetadata {
method not_found (line 107) | pub fn not_found() -> Self {
method from (line 134) | fn from(value: StdMetadata) -> Self {
method into_lua (line 120) | fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
function system_time_to_timestamp (line 146) | fn system_time_to_timestamp(res: IoResult<SystemTime>) -> Option<DateTim...
FILE: crates/lune-std-fs/src/options.rs
type FsWriteOptions (line 4) | pub struct FsWriteOptions {
method from_lua (line 9) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
FILE: crates/lune-std-luau/src/lib.rs
constant TYPEDEFS (line 11) | const TYPEDEFS: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), ...
function typedefs (line 17) | pub fn typedefs() -> String {
function module (line 28) | pub fn module(lua: Lua) -> LuaResult<LuaTable> {
function compile_source (line 35) | fn compile_source(
function load_source (line 45) | fn load_source(
FILE: crates/lune-std-luau/src/options.rs
constant DEFAULT_DEBUG_NAME (line 6) | const DEFAULT_DEBUG_NAME: &str = "luau.load(...)";
type LuauCompileOptions (line 12) | pub struct LuauCompileOptions {
method into_compiler (line 19) | pub fn into_compiler(self) -> LuaCompiler {
method default (line 28) | fn default() -> Self {
method from_lua (line 40) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
type LuauLoadOptions (line 82) | pub struct LuauLoadOptions {
method default (line 90) | fn default() -> Self {
method from_lua (line 101) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
FILE: crates/lune-std-net/src/body/cursor.rs
type ReadableBodyCursor (line 9) | pub struct ReadableBodyCursor {
method len (line 15) | pub fn len(&self) -> usize {
method as_slice (line 19) | pub fn as_slice(&self) -> &[u8] {
method advance (line 23) | pub fn advance(&mut self, cnt: usize) {
method into_bytes (line 30) | pub fn into_bytes(self) -> Bytes {
method from (line 53) | fn from(value: T) -> Self {
method remaining (line 36) | fn remaining(&self) -> usize {
method chunk (line 40) | fn chunk(&self) -> &[u8] {
method advance (line 44) | fn advance(&mut self, cnt: usize) {
FILE: crates/lune-std-net/src/body/incoming.rs
function handle_incoming_body (line 12) | pub async fn handle_incoming_body(
FILE: crates/lune-std-net/src/body/inner.rs
type ReadableBodyInner (line 8) | pub enum ReadableBodyInner {
method len (line 16) | pub fn len(&self) -> usize {
method as_slice (line 25) | pub fn as_slice(&self) -> &[u8] {
method into_bytes (line 66) | pub fn into_bytes(self) -> Bytes {
method from (line 77) | fn from(value: &'static str) -> Self {
method from (line 83) | fn from(value: Vec<u8>) -> Self {
method from (line 89) | fn from(value: Bytes) -> Self {
method from (line 95) | fn from(value: String) -> Self {
method from (line 101) | fn from(value: LuaString) -> Self {
method from (line 107) | fn from(value: LuaBuffer) -> Self {
FILE: crates/lune-std-net/src/body/readable.rs
type ReadableBody (line 20) | pub struct ReadableBody {
method empty (line 25) | pub const fn empty() -> Self {
method as_slice (line 29) | pub fn as_slice(&self) -> &[u8] {
method into_bytes (line 36) | pub fn into_bytes(self) -> Bytes {
method from (line 71) | fn from(value: T) -> Self {
method from (line 82) | fn from(value: Option<T>) -> Self {
type Data (line 45) | type Data = ReadableBodyCursor;
type Error (line 46) | type Error = Infallible;
method poll_frame (line 48) | fn poll_frame(
method is_end_stream (line 55) | fn is_end_stream(&self) -> bool {
method size_hint (line 59) | fn size_hint(&self) -> SizeHint {
method from_lua (line 90) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
FILE: crates/lune-std-net/src/client/fetch.rs
function fetch (line 33) | pub async fn fetch(
function fetch_inner (line 83) | async fn fetch_inner(
FILE: crates/lune-std-net/src/client/mod.rs
constant MAX_REDIRECTS (line 25) | const MAX_REDIRECTS: usize = 10;
function connect_ws (line 30) | pub async fn connect_ws(url: Url) -> LuaResult<Websocket<WsStream>> {
function connect_tcp (line 38) | pub async fn connect_tcp(host: String, port: u16, config: TcpConfig) -> ...
function try_follow_redirect (line 52) | fn try_follow_redirect(
function check_redirect (line 87) | fn check_redirect(method: Method, response: &HyperResponse<Incoming>) ->...
FILE: crates/lune-std-net/src/client/rustls.rs
function initialize_provider (line 10) | pub fn initialize_provider() {
FILE: crates/lune-std-net/src/client/send.rs
function send (line 27) | pub async fn send(mut request: Request, lua: Lua) -> LuaResult<Response> {
FILE: crates/lune-std-net/src/client/stream.rs
type HttpStream (line 26) | pub type HttpStream = MaybeTlsStream;
type MaybeTlsStream (line 36) | pub enum MaybeTlsStream {
method connect (line 50) | pub async fn connect(host: &str, port: u16, tls: bool) -> Result<Self> {
method connect_url (line 70) | pub async fn connect_url(url: Url) -> Result<Self> {
method local_addr (line 91) | pub fn local_addr(&self) -> Result<SocketAddr> {
method remote_addr (line 98) | pub fn remote_addr(&self) -> Result<SocketAddr> {
method set_ttl (line 107) | pub fn set_ttl(&self, ttl: u32) -> Result<()> {
method as_ref (line 113) | fn as_ref(&self) -> &TcpStream {
method from (line 122) | fn from(stream: TcpStream) -> Self {
method from (line 128) | fn from(stream: TlsStream<TcpStream>) -> Self {
method poll_read (line 134) | fn poll_read(
method poll_write (line 147) | fn poll_write(
method poll_close (line 158) | fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Re...
method poll_flush (line 165) | fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Re...
type WsStream (line 179) | pub struct WsStream {
method connect_url (line 189) | pub async fn connect_url(url: Url) -> Result<Self> {
type Error (line 202) | type Error = TungsteniteError;
method poll_ready (line 204) | fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<...
method start_send (line 208) | fn start_send(mut self: Pin<&mut Self>, item: Message) -> TungsteniteR...
method poll_flush (line 212) | fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<...
method poll_close (line 216) | fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<...
type Item (line 222) | type Item = TungsteniteResult<Message>;
method poll_next (line 224) | fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Opt...
FILE: crates/lune-std-net/src/client/tcp.rs
type TcpConfig (line 4) | pub struct TcpConfig {
method from_lua (line 10) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
FILE: crates/lune-std-net/src/lib.rs
constant TYPEDEFS (line 22) | const TYPEDEFS: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), ...
function typedefs (line 28) | pub fn typedefs() -> String {
function module (line 39) | pub fn module(lua: Lua) -> LuaResult<LuaTable> {
function net_http_request (line 67) | async fn net_http_request(lua: Lua, req: Request) -> LuaResult<Response> {
function net_http_serve (line 71) | async fn net_http_serve(lua: Lua, (port, config): (u16, ServeConfig)) ->...
function net_tcp_connect (line 77) | async fn net_tcp_connect(_: Lua, (host, port, config): (String, u16, Tcp...
function net_ws_connect (line 81) | async fn net_ws_connect(_: Lua, url: String) -> LuaResult<Websocket<WsSt...
function net_url_encode (line 86) | fn net_url_encode(
function net_url_decode (line 95) | fn net_url_decode(
FILE: crates/lune-std-net/src/server/config.rs
constant DEFAULT_IP_ADDRESS (line 5) | const DEFAULT_IP_ADDRESS: IpAddr = IpAddr::V4(Ipv4Addr::LOCALHOST);
constant WEB_SOCKET_UPDGRADE_REQUEST_HANDLER (line 7) | const WEB_SOCKET_UPDGRADE_REQUEST_HANDLER: &str = r#"
type ServeConfig (line 18) | pub struct ServeConfig {
method from_lua (line 25) | fn from_lua(value: LuaValue, lua: &Lua) -> LuaResult<Self> {
FILE: crates/lune-std-net/src/server/handle.rs
type ServeHandle (line 15) | pub struct ServeHandle {
method new (line 22) | pub fn new(addr: SocketAddr) -> (Self, Receiver<()>) {
method into_lua_table (line 34) | pub fn into_lua_table(self, lua: Lua) -> LuaResult<LuaTable> {
method add_fields (line 55) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 60) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
FILE: crates/lune-std-net/src/server/mod.rs
function serve (line 28) | pub async fn serve(lua: Lua, port: u16, config: ServeConfig) -> LuaResul...
FILE: crates/lune-std-net/src/server/service.rs
type Service (line 22) | pub(super) struct Service {
type Response (line 29) | type Response = HyperResponse<ReadableBody>;
type Error (line 30) | type Error = LuaError;
type Future (line 31) | type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self:...
method call (line 33) | fn call(&self, req: HyperRequest<Incoming>) -> Self::Future {
function handle_request (line 80) | async fn handle_request(
function handle_websocket (line 102) | async fn handle_websocket(
FILE: crates/lune-std-net/src/server/upgrade.rs
constant SEC_WEBSOCKET_VERSION (line 11) | const SEC_WEBSOCKET_VERSION: HeaderName = HeaderName::from_static("sec-w...
constant SEC_WEBSOCKET_KEY (line 12) | const SEC_WEBSOCKET_KEY: HeaderName = HeaderName::from_static("sec-webso...
constant SEC_WEBSOCKET_ACCEPT (line 13) | const SEC_WEBSOCKET_ACCEPT: HeaderName = HeaderName::from_static("sec-we...
function is_upgrade_request (line 15) | pub fn is_upgrade_request(request: &HyperRequest<Incoming>) -> bool {
function make_upgrade_response (line 33) | pub fn make_upgrade_response(
FILE: crates/lune-std-net/src/shared/futures.rs
function either (line 12) | pub fn either<L: Future, R: Future>(
FILE: crates/lune-std-net/src/shared/headers.rs
function create_user_agent_header (line 11) | pub fn create_user_agent_header(lua: &Lua) -> LuaResult<String> {
function header_map_to_table (line 26) | pub fn header_map_to_table(
function hash_map_to_table (line 47) | pub fn hash_map_to_table(
FILE: crates/lune-std-net/src/shared/hyper.rs
type HyperExecutor (line 19) | pub struct HyperExecutor {
method attach (line 25) | pub fn attach(lua: &Lua) -> mlua::AppDataRef<'_, Self> {
method execute (line 30) | pub fn execute<Fut>(lua: Lua, fut: Fut)
method execute (line 47) | fn execute(&self, fut: Fut) {
type HyperTimer (line 55) | pub struct HyperTimer;
method sleep (line 58) | fn sleep(&self, duration: Duration) -> Pin<Box<dyn rt::Sleep>> {
method sleep_until (line 62) | fn sleep_until(&self, at: Instant) -> Pin<Box<dyn rt::Sleep>> {
method reset (line 66) | fn reset(&self, sleep: &mut Pin<Box<dyn rt::Sleep>>, new_deadline: Ins...
type HyperSleep (line 76) | pub struct HyperSleep {
method from (line 81) | fn from(inner: Timer) -> Self {
type Output (line 87) | type Output = ();
method poll (line 89) | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
function from (line 111) | fn from(inner: T) -> Self {
function pin_mut (line 117) | pub fn pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
function poll_read (line 125) | fn poll_read(
function poll_write (line 153) | fn poll_write(
function poll_flush (line 161) | fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Re...
function poll_shutdown (line 165) | fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io:...
method poll_read (line 173) | fn poll_read(
method poll_write (line 185) | fn poll_write(
method poll_flush (line 193) | fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result...
method poll_close (line 197) | fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Re...
FILE: crates/lune-std-net/src/shared/lua.rs
function lua_value_to_method (line 8) | pub fn lua_value_to_method(value: &LuaValue) -> LuaResult<Method> {
function lua_table_to_header_map (line 30) | pub fn lua_table_to_header_map(table: &LuaTable) -> LuaResult<HeaderMap> {
FILE: crates/lune-std-net/src/shared/request.rs
type RequestOptions (line 18) | pub struct RequestOptions {
method default (line 23) | fn default() -> Self {
method from_lua (line 29) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
type Request (line 57) | pub struct Request {
method from_incoming (line 68) | pub async fn from_incoming(
method with_address (line 89) | pub fn with_address(mut self, address: SocketAddr) -> Self {
method method (line 97) | pub fn method(&self) -> Method {
method path (line 104) | pub fn path(&self) -> &str {
method query (line 111) | pub fn query(&self) -> HashMap<String, Vec<String>> {
method headers (line 131) | pub fn headers(&self) -> &HeaderMap {
method body (line 138) | pub fn body(&self) -> &[u8] {
method clone_inner (line 146) | pub fn clone_inner(&self) -> HyperRequest<ReadableBody> {
method into_inner (line 154) | pub fn into_inner(self) -> HyperRequest<ReadableBody> {
method from (line 160) | fn from(inner: HyperRequest<B>) -> Self {
method from_lua (line 172) | fn from_lua(value: LuaValue, lua: &Lua) -> LuaResult<Self> {
method add_fields (line 251) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
FILE: crates/lune-std-net/src/shared/response.rs
type Response (line 15) | pub struct Response {
method from_incoming (line 24) | pub async fn from_incoming(
method status_ok (line 41) | pub fn status_ok(&self) -> bool {
method status_code (line 48) | pub fn status_code(&self) -> u16 {
method status_message (line 55) | pub fn status_message(&self) -> &str {
method headers (line 62) | pub fn headers(&self) -> &HeaderMap {
method body (line 69) | pub fn body(&self) -> &[u8] {
method clone_inner (line 77) | pub fn clone_inner(&self) -> HyperResponse<ReadableBody> {
method into_inner (line 85) | pub fn into_inner(self) -> HyperResponse<ReadableBody> {
method from_lua (line 91) | fn from_lua(value: LuaValue, lua: &Lua) -> LuaResult<Self> {
method add_fields (line 142) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
FILE: crates/lune-std-net/src/shared/tcp.rs
constant DEFAULT_BUFFER_SIZE (line 14) | const DEFAULT_BUFFER_SIZE: usize = 1024;
type Tcp (line 17) | pub struct Tcp {
method read (line 25) | async fn read(&self, size: usize) -> Result<Vec<u8>, Error> {
method write (line 36) | async fn write(&self, data: Vec<u8>) -> Result<(), Error> {
method close (line 43) | async fn close(&self) -> Result<(), Error> {
method from (line 56) | fn from(value: T) -> Self {
method add_fields (line 74) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 89) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
FILE: crates/lune-std-net/src/shared/websocket.rs
type Websocket (line 24) | pub struct Websocket<T> {
function get_close_code (line 36) | fn get_close_code(&self) -> Option<u16> {
function set_close_code (line 44) | fn set_close_code(&self, code: u16) {
function send (line 49) | pub async fn send(&self, msg: TungsteniteMessage) -> LuaResult<()> {
function next (line 54) | pub async fn next(&self) -> LuaResult<Option<TungsteniteMessage>> {
function close (line 59) | pub async fn close(&self, code: Option<u16>) -> LuaResult<()> {
function from (line 88) | fn from(value: T) -> Self {
method add_fields (line 105) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 109) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
FILE: crates/lune-std-net/src/url/decode.rs
function decode (line 3) | pub fn decode(lua_string: LuaString, as_binary: bool) -> LuaResult<Vec<u...
FILE: crates/lune-std-net/src/url/encode.rs
function encode (line 3) | pub fn encode(lua_string: LuaString, as_binary: bool) -> LuaResult<Vec<u...
FILE: crates/lune-std-process/src/create/child.rs
type Child (line 15) | pub struct Child {
method new (line 24) | pub fn new(lua: &Lua, mut child: AsyncChild) -> Self {
method add_fields (line 46) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 52) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
function handle_child (line 71) | async fn handle_child(
FILE: crates/lune-std-process/src/create/child_reader.rs
constant DEFAULT_BUFFER_SIZE (line 9) | const DEFAULT_BUFFER_SIZE: usize = 1024;
type ChildReaderInner (line 14) | enum ChildReaderInner {
method read (line 21) | async fn read(&mut self, size: usize) -> Result<Vec<u8>, std::io::Erro...
method read_to_end (line 39) | async fn read_to_end(&mut self) -> Result<Vec<u8>, std::io::Error> {
method from (line 58) | fn from(stdout: AsyncChildStdout) -> Self {
method from (line 64) | fn from(stderr: AsyncChildStderr) -> Self {
method from (line 70) | fn from(stdout: Option<AsyncChildStdout>) -> Self {
method from (line 76) | fn from(stderr: Option<AsyncChildStderr>) -> Self {
type ChildReader (line 84) | pub struct ChildReader {
method from (line 115) | fn from(inner: T) -> Self {
method add_methods (line 89) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
FILE: crates/lune-std-process/src/create/child_writer.rs
type ChildWriterInner (line 13) | enum ChildWriterInner {
method write (line 19) | async fn write(&mut self, data: Vec<u8>) -> Result<(), std::io::Error> {
method close (line 26) | async fn close(&mut self) -> Result<(), std::io::Error> {
method from (line 35) | fn from(stdin: AsyncChildStdin) -> Self {
method from (line 41) | fn from(stdin: Option<AsyncChildStdin>) -> Self {
type ChildWriter (line 49) | pub struct ChildWriter {
method from (line 74) | fn from(inner: T) -> Self {
method add_methods (line 54) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
FILE: crates/lune-std-process/src/exec/mod.rs
function exec (line 15) | pub async fn exec(
FILE: crates/lune-std-process/src/exec/tee_writer.rs
type AsyncTeeWriter (line 11) | pub struct AsyncTeeWriter<'a, W>
function new (line 24) | pub fn new(writer: &'a mut W) -> Self {
function into_vec (line 31) | pub fn into_vec(self) -> Vec<u8> {
method poll_write (line 40) | fn poll_write(
method poll_flush (line 56) | fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Re...
method poll_close (line 60) | fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Re...
FILE: crates/lune-std-process/src/exec/wait_for_child.rs
type WaitForChildResult (line 14) | pub(super) struct WaitForChildResult {
function read_with_stdio_kind (line 20) | async fn read_with_stdio_kind<R>(
function wait_for_child (line 53) | pub(super) async fn wait_for_child(
FILE: crates/lune-std-process/src/lib.rs
constant TYPEDEFS (line 24) | const TYPEDEFS: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), ...
function typedefs (line 30) | pub fn typedefs() -> String {
function module (line 42) | pub fn module(lua: Lua) -> LuaResult<LuaTable> {
function process_exec (line 91) | async fn process_exec(
function process_create (line 115) | fn process_create(
FILE: crates/lune-std-process/src/options/kind.rs
type ProcessSpawnOptionsStdioKind (line 6) | pub enum ProcessSpawnOptionsStdioKind {
method all (line 17) | pub fn all() -> &'static [Self] {
method as_stdio (line 21) | pub fn as_stdio(self) -> Stdio {
method fmt (line 31) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type Err (line 43) | type Err = LuaError;
method from_str (line 44) | fn from_str(s: &str) -> Result<Self, Self::Err> {
method from_lua (line 66) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
FILE: crates/lune-std-process/src/options/mod.rs
type ProcessSpawnOptions (line 21) | pub(super) struct ProcessSpawnOptions {
method into_command (line 134) | pub fn into_command(self, program: impl Into<OsString>, args: ProcessA...
method from_lua (line 29) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
FILE: crates/lune-std-process/src/options/stdio.rs
type ProcessSpawnOptionsStdio (line 7) | pub struct ProcessSpawnOptionsStdio {
method from (line 14) | fn from(value: ProcessSpawnOptionsStdioKind) -> Self {
method from_lua (line 24) | fn from_lua(value: LuaValue, lua: &Lua) -> LuaResult<Self> {
FILE: crates/lune-std-regex/src/captures.rs
type OptionalCaptures (line 9) | type OptionalCaptures<'a> = Option<Captures<'a>>;
type LuaCaptures (line 22) | pub struct LuaCaptures {
method new (line 32) | pub fn new(pattern: &Regex, text: String) -> Option<Self> {
method captures (line 42) | fn captures(&self) -> &Captures<'_> {
method num_captures (line 49) | fn num_captures(&self) -> usize {
method text (line 55) | fn text(&self) -> Arc<String> {
method add_methods (line 61) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method add_fields (line 88) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
FILE: crates/lune-std-regex/src/lib.rs
constant TYPEDEFS (line 13) | const TYPEDEFS: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), ...
function typedefs (line 19) | pub fn typedefs() -> String {
function module (line 30) | pub fn module(lua: Lua) -> LuaResult<LuaTable> {
function new_regex (line 36) | fn new_regex(_: &Lua, pattern: String) -> LuaResult<LuaRegex> {
FILE: crates/lune-std-regex/src/matches.rs
type LuaMatch (line 9) | pub struct LuaMatch {
method new (line 19) | pub fn new(text: Arc<String>, matched: Match) -> Self {
method range (line 27) | fn range(&self) -> Range<usize> {
method slice (line 31) | fn slice(&self) -> &str {
method add_fields (line 37) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
method add_methods (line 47) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
FILE: crates/lune-std-regex/src/regex.rs
type LuaRegex (line 12) | pub struct LuaRegex {
method new (line 20) | pub fn new(pattern: String) -> LuaResult<Self> {
method add_methods (line 28) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
method add_fields (line 73) | fn add_fields<F: LuaUserDataFields<Self>>(fields: &mut F) {
FILE: crates/lune-std-roblox/src/lib.rs
constant TYPEDEFS (line 19) | const TYPEDEFS: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), ...
function typedefs (line 25) | pub fn typedefs() -> String {
function module (line 36) | pub fn module(lua: Lua) -> LuaResult<LuaTable> {
function deserialize_place (line 61) | async fn deserialize_place(lua: Lua, contents: LuaString) -> LuaResult<L...
function deserialize_model (line 71) | async fn deserialize_model(lua: Lua, contents: LuaString) -> LuaResult<L...
function serialize_place (line 81) | async fn serialize_place(
function serialize_model (line 98) | async fn serialize_model(
function get_auth_cookie (line 115) | fn get_auth_cookie(_: &Lua, raw: Option<bool>) -> LuaResult<Option<Strin...
function get_reflection_database (line 123) | fn get_reflection_database(_: &Lua, _: ()) -> LuaResult<ReflectionDataba...
function implement_property (line 127) | fn implement_property(
function implement_method (line 153) | fn implement_method(
function studio_application_path (line 161) | fn studio_application_path(_: &Lua, _: ()) -> LuaResult<String> {
function studio_content_path (line 167) | fn studio_content_path(_: &Lua, _: ()) -> LuaResult<String> {
function studio_plugin_path (line 173) | fn studio_plugin_path(_: &Lua, _: ()) -> LuaResult<String> {
function studio_builtin_plugin_path (line 179) | fn studio_builtin_plugin_path(_: &Lua, _: ()) -> LuaResult<String> {
FILE: crates/lune-std-serde/src/compress_decompress.rs
type CompressDecompressFormat (line 22) | pub enum CompressDecompressFormat {
method detect_from_bytes (line 36) | pub fn detect_from_bytes(bytes: impl AsRef<[u8]>) -> Option<Self> {
method detect_from_header_str (line 82) | pub fn detect_from_header_str(header: impl AsRef<str>) -> Option<Self> {
method from_lua (line 95) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
function compress (line 128) | pub async fn compress(
function decompress (line 175) | pub async fn decompress(
function compress_lz4 (line 214) | fn compress_lz4(input: Vec<u8>) -> LuaResult<Vec<u8>> {
function decompress_lz4 (line 235) | fn decompress_lz4(input: Vec<u8>) -> LuaResult<Vec<u8>> {
FILE: crates/lune-std-serde/src/encode_decode.rs
constant LUA_SERIALIZE_OPTIONS (line 8) | const LUA_SERIALIZE_OPTIONS: LuaSerializeOptions = LuaSerializeOptions::...
constant LUA_DESERIALIZE_OPTIONS (line 14) | const LUA_DESERIALIZE_OPTIONS: LuaDeserializeOptions = LuaDeserializeOpt...
type EncodeDecodeFormat (line 25) | pub enum EncodeDecodeFormat {
method from_lua (line 33) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
type EncodeDecodeConfig (line 64) | pub struct EncodeDecodeConfig {
method from (line 70) | fn from(format: EncodeDecodeFormat) -> Self {
method from (line 79) | fn from(value: (EncodeDecodeFormat, bool)) -> Self {
function encode (line 94) | pub fn encode(value: LuaValue, lua: &Lua, config: EncodeDecodeConfig) ->...
function decode (line 130) | pub fn decode(
FILE: crates/lune-std-serde/src/hash.rs
type HashOptions (line 12) | pub struct HashOptions {
method hash (line 76) | pub fn hash(self) -> String {
method hmac (line 116) | pub fn hmac(self) -> LuaResult<String> {
type HashAlgorithm (line 20) | enum HashAlgorithm {
constant ALL (line 38) | pub const ALL: [Self; 11] = [
method name (line 52) | pub const fn name(self) -> &'static str {
method from_lua (line 178) | fn from_lua(value: LuaValue, _lua: &Lua) -> LuaResult<Self> {
method from_lua_multi (line 225) | fn from_lua_multi(mut values: LuaMultiValue, lua: &Lua) -> LuaResult<Sel...
FILE: crates/lune-std-serde/src/lib.rs
constant TYPEDEFS (line 16) | const TYPEDEFS: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), ...
function typedefs (line 22) | pub fn typedefs() -> String {
function module (line 33) | pub fn module(lua: Lua) -> LuaResult<LuaTable> {
function serde_encode (line 44) | fn serde_encode(
function serde_decode (line 52) | fn serde_decode(lua: &Lua, (format, bs): (EncodeDecodeFormat, BString)) ...
function serde_compress (line 57) | async fn serde_compress(
function serde_decompress (line 65) | async fn serde_decompress(
function hash_message (line 73) | fn hash_message(lua: &Lua, options: HashOptions) -> LuaResult<LuaString> {
function hmac_message (line 77) | fn hmac_message(lua: &Lua, options: HashOptions) -> LuaResult<LuaString> {
FILE: crates/lune-std-stdio/src/lib.rs
constant FORMAT_CONFIG (line 26) | const FORMAT_CONFIG: ValueFormatConfig = ValueFormatConfig::new()
constant TYPEDEFS (line 36) | const TYPEDEFS: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), ...
function typedefs (line 42) | pub fn typedefs() -> String {
function module (line 53) | pub fn module(lua: Lua) -> LuaResult<LuaTable> {
function stdio_color (line 66) | fn stdio_color(lua: &Lua, color: ColorKind) -> LuaResult<LuaValue> {
function stdio_style (line 70) | fn stdio_style(lua: &Lua, style: StyleKind) -> LuaResult<LuaValue> {
function stdio_format (line 74) | fn stdio_format(_: &Lua, args: LuaMultiValue) -> LuaResult<String> {
function stdio_write (line 78) | async fn stdio_write(_: Lua, s: LuaString) -> LuaResult<()> {
function stdio_ewrite (line 85) | async fn stdio_ewrite(_: Lua, s: LuaString) -> LuaResult<()> {
function stdio_read_line (line 92) | async fn stdio_read_line(lua: Lua, (): ()) -> LuaResult<LuaString> {
function stdio_read_to_end (line 99) | async fn stdio_read_to_end(lua: Lua, (): ()) -> LuaResult<LuaString> {
function stdio_prompt (line 106) | async fn stdio_prompt(lua: Lua, options: PromptOptions) -> LuaResult<Pro...
FILE: crates/lune-std-stdio/src/prompt.rs
type PromptKind (line 7) | pub enum PromptKind {
constant ALL (line 15) | const ALL: [PromptKind; 4] = [Self::Text, Self::Confirm, Self::Select,...
method fmt (line 38) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method default (line 19) | fn default() -> Self {
type Err (line 25) | type Err = ();
method from_str (line 26) | fn from_str(s: &str) -> Result<Self, Self::Err> {
method from_lua (line 53) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
type PromptOptions (line 80) | pub struct PromptOptions {
method from_lua_multi (line 89) | fn from_lua_multi(mut values: LuaMultiValue, lua: &Lua) -> LuaResult<Sel...
type PromptResult (line 159) | pub enum PromptResult {
method into_lua (line 168) | fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
function prompt (line 179) | pub fn prompt(options: PromptOptions) -> LuaResult<PromptResult> {
FILE: crates/lune-std-stdio/src/style_and_color.rs
constant ESCAPE_SEQ_RESET (line 5) | const ESCAPE_SEQ_RESET: &str = "\x1b[0m";
type ColorKind (line 11) | pub enum ColorKind {
constant ALL (line 24) | pub const ALL: [Self; 9] = [
method name (line 39) | pub fn name(self) -> &'static str {
method ansi_escape_sequence (line 56) | pub fn ansi_escape_sequence(self) -> &'static str {
type Err (line 72) | type Err = ();
method from_str (line 73) | fn from_str(s: &str) -> Result<Self, Self::Err> {
method from_lua (line 92) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
type StyleKind (line 124) | pub enum StyleKind {
constant ALL (line 131) | pub const ALL: [Self; 3] = [Self::Reset, Self::Bold, Self::Dim];
method name (line 136) | pub fn name(self) -> &'static str {
method ansi_escape_sequence (line 147) | pub fn ansi_escape_sequence(self) -> &'static str {
type Err (line 157) | type Err = ();
method from_str (line 158) | fn from_str(s: &str) -> Result<Self, Self::Err> {
method from_lua (line 169) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
FILE: crates/lune-std-task/src/lib.rs
constant TYPEDEFS (line 13) | const TYPEDEFS: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), ...
function typedefs (line 19) | pub fn typedefs() -> String {
function module (line 30) | pub fn module(lua: Lua) -> LuaResult<LuaTable> {
constant DELAY_IMPL_LUA (line 56) | const DELAY_IMPL_LUA: &str = r"
function wait (line 63) | async fn wait(lua: Lua, secs: Option<f64>) -> LuaResult<f64> {
function wait_inner (line 70) | async fn wait_inner(_: Lua, secs: Option<f64>) -> LuaResult<f64> {
FILE: crates/lune-std/src/global.rs
type LuneStandardGlobal (line 9) | pub enum LuneStandardGlobal {
constant ALL (line 21) | pub const ALL: &'static [Self] = &[
method name (line 33) | pub fn name(&self) -> &'static str {
method create (line 52) | pub fn create(&self, lua: Lua) -> LuaResult<LuaValue> {
type Err (line 71) | type Err = String;
method from_str (line 72) | fn from_str(s: &str) -> Result<Self, Self::Err> {
FILE: crates/lune-std/src/globals/g_table.rs
function create (line 3) | pub fn create(lua: Lua) -> LuaResult<LuaValue> {
FILE: crates/lune-std/src/globals/print.rs
constant FORMAT_CONFIG (line 6) | const FORMAT_CONFIG: ValueFormatConfig = ValueFormatConfig::new()
function create (line 10) | pub fn create(lua: Lua) -> LuaResult<LuaValue> {
FILE: crates/lune-std/src/globals/require.rs
function create (line 5) | pub fn create(lua: Lua) -> LuaResult<LuaValue> {
FILE: crates/lune-std/src/globals/version.rs
type Version (line 5) | struct Version(String);
function create (line 9) | pub fn create(lua: Lua) -> LuaResult<LuaValue> {
function set_global_version (line 31) | pub fn set_global_version(lua: &Lua, version: impl Into<String>) {
FILE: crates/lune-std/src/globals/warn.rs
constant FORMAT_CONFIG (line 6) | const FORMAT_CONFIG: ValueFormatConfig = ValueFormatConfig::new()
function create (line 10) | pub fn create(lua: Lua) -> LuaResult<LuaValue> {
FILE: crates/lune-std/src/lib.rs
function inject_globals (line 23) | pub fn inject_globals(lua: Lua) -> LuaResult<()> {
function inject_std (line 38) | pub fn inject_std(lua: Lua) -> LuaResult<()> {
FILE: crates/lune-std/src/library.rs
type LuneStandardLibrary (line 10) | pub enum LuneStandardLibrary {
constant ALL (line 28) | pub const ALL: &'static [Self] = &[
method name (line 47) | pub fn name(&self) -> &'static str {
method typedefs (line 70) | pub fn typedefs(&self) -> String {
method module (line 96) | pub fn module(&self, lua: Lua) -> LuaResult<LuaTable> {
type Err (line 123) | type Err = String;
method from_str (line 125) | fn from_str(s: &str) -> Result<Self, Self::Err> {
FILE: crates/lune-std/src/require/loader.rs
type RequireResult (line 15) | type RequireResult = LuaResult<LuaMultiValue>;
type RequireResultSender (line 16) | type RequireResultSender = Sender<RequireResult>;
type RequireResultReceiver (line 17) | type RequireResultReceiver = Receiver<RequireResult>;
type RequireLoaderState (line 23) | struct RequireLoaderState {
method new (line 29) | fn new() -> Self {
method get_pending_at_path (line 36) | fn get_pending_at_path(&self, path: &Path) -> Option<RequireResultRece...
method create_pending_at_path (line 40) | fn create_pending_at_path(&self, path: &Path) -> RequireResultSender {
method remove_pending_at_path (line 47) | fn remove_pending_at_path(&self, path: &Path) {
type RequireLoader (line 58) | pub(crate) struct RequireLoader {
method new (line 63) | pub(crate) fn new() -> Self {
method load (line 69) | pub(crate) fn load(
FILE: crates/lune-std/src/require/resolver.rs
type RequireResolver (line 17) | pub(crate) struct RequireResolver {
method new (line 36) | pub(crate) fn new() -> Self {
method navigate_reset (line 45) | fn navigate_reset(&mut self) {
method navigate_to (line 51) | fn navigate_to(
method is_require_allowed (line 75) | fn is_require_allowed(&self, chunk_name: &str) -> bool {
method reset (line 79) | fn reset(&mut self, chunk_name: &str) -> Result<(), LuaNavigateError> {
method jump_to_alias (line 98) | fn jump_to_alias(&mut self, path: &str) -> Result<(), LuaNavigateError> {
method to_parent (line 105) | fn to_parent(&mut self) -> Result<(), LuaNavigateError> {
method to_child (line 130) | fn to_child(&mut self, name: &str) -> Result<(), LuaNavigateError> {
method has_module (line 137) | fn has_module(&self) -> bool {
method cache_key (line 142) | fn cache_key(&self) -> String {
method has_config (line 147) | fn has_config(&self) -> bool {
method config (line 151) | fn config(&self) -> IoResult<Vec<u8>> {
method loader (line 155) | fn loader(&self, lua: &Lua) -> LuaResult<LuaFunction> {
FILE: crates/lune-utils/src/fmt/error/components.rs
constant STACK_TRACE_INDENT (line 33) | const STACK_TRACE_INDENT: &str = " ";
type ErrorComponents (line 51) | pub struct ErrorComponents {
method messages (line 61) | pub fn messages(&self) -> &[String] {
method trace (line 69) | pub fn trace(&self) -> Option<&StackTrace> {
method has_trace (line 79) | pub fn has_trace(&self) -> bool {
method fmt (line 87) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
method from (line 104) | fn from(error: LuaError) -> Self {
method from (line 204) | fn from(value: Box<LuaError>) -> Self {
FILE: crates/lune-utils/src/fmt/error/stack_trace.rs
function unwrap_braced_path (line 4) | fn unwrap_braced_path(s: &str) -> &str {
function parse_path (line 10) | fn parse_path(s: &str) -> Option<(&str, &str)> {
function parse_function_name (line 24) | fn parse_function_name(s: &str) -> Option<&str> {
function parse_line_number (line 29) | fn parse_line_number(s: &str) -> (Option<usize>, &str) {
type StackTraceSource (line 40) | pub enum StackTraceSource {
method is_c (line 53) | pub const fn is_c(self) -> bool {
method is_lua (line 61) | pub const fn is_lua(self) -> bool {
type StackTraceLine (line 70) | pub struct StackTraceLine {
method source (line 82) | pub fn source(&self) -> StackTraceSource {
method path (line 90) | pub fn path(&self) -> Option<&str> {
method line_number (line 98) | pub fn line_number(&self) -> Option<usize> {
method function_name (line 106) | pub fn function_name(&self) -> Option<&str> {
method is_empty (line 120) | pub const fn is_empty(&self) -> bool {
method fmt (line 154) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type Err (line 126) | type Err = String;
method from_str (line 127) | fn from_str(s: &str) -> Result<Self, Self::Err> {
type StackTrace (line 174) | pub struct StackTrace {
method lines (line 183) | pub fn lines(&self) -> &[StackTraceLine] {
method lines_mut (line 191) | pub fn lines_mut(&mut self) -> &mut Vec<StackTraceLine> {
type Err (line 197) | type Err = String;
method from_str (line 198) | fn from_str(s: &str) -> Result<Self, Self::Err> {
FILE: crates/lune-utils/src/fmt/error/tests.rs
function new_lua_runtime_error (line 5) | fn new_lua_runtime_error() -> LuaResult<()> {
function new_lua_script_error (line 18) | fn new_lua_script_error() -> LuaResult<()> {
function preserves_original (line 42) | fn preserves_original() {
function preserves_levels (line 53) | fn preserves_levels() {
function message (line 75) | fn message() {
function stack_begin_end (line 83) | fn stack_begin_end() {
function stack_lines (line 92) | fn stack_lines() {
function message_does_not_contain_location (line 111) | fn message_does_not_contain_location() {
function no_redundant_c_mentions (line 134) | fn no_redundant_c_mentions() {
FILE: crates/lune-utils/src/fmt/label.rs
type Label (line 24) | pub enum Label {
method name (line 35) | pub fn name(&self) -> &str {
method color (line 47) | pub fn color(&self) -> Color {
method fmt (line 57) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
FILE: crates/lune-utils/src/fmt/value/basic.rs
constant STRING_REPLACEMENTS (line 13) | const STRING_REPLACEMENTS: &[(&str, &str)] =
function lua_value_as_plain_string_key (line 24) | pub(crate) fn lua_value_as_plain_string_key(value: &LuaValue) -> Option<...
function format_value_styled (line 42) | pub(crate) fn format_value_styled(value: &LuaValue, prefer_plain: bool) ...
function format_typename_and_tostringed (line 90) | fn format_typename_and_tostringed(
FILE: crates/lune-utils/src/fmt/value/config.rs
type ValueFormatConfig (line 5) | pub struct ValueFormatConfig {
method new (line 15) | pub const fn new() -> Self {
method with_max_depth (line 26) | pub const fn with_max_depth(self, max_depth: usize) -> Self {
method with_colors_enabled (line 36) | pub const fn with_colors_enabled(self, colors_enabled: bool) -> Self {
method default (line 45) | fn default() -> Self {
FILE: crates/lune-utils/src/fmt/value/metamethods.rs
function get_table_type_metavalue (line 3) | pub fn get_table_type_metavalue(tab: &LuaTable) -> Option<String> {
function get_userdata_type_metavalue (line 10) | pub fn get_userdata_type_metavalue(usr: &LuaAnyUserData) -> Option<Strin...
function call_table_tostring_metamethod (line 17) | pub fn call_table_tostring_metamethod(tab: &LuaTable) -> Option<String> {
function call_userdata_tostring_metamethod (line 27) | pub fn call_userdata_tostring_metamethod(usr: &LuaAnyUserData) -> Option...
FILE: crates/lune-utils/src/fmt/value/mod.rs
function pretty_format_value (line 31) | pub fn pretty_format_value(value: &LuaValue, config: &ValueFormatConfig)...
function pretty_format_multi_value (line 51) | pub fn pretty_format_multi_value(values: &LuaMultiValue, config: &ValueF...
FILE: crates/lune-utils/src/fmt/value/recursive.rs
constant INDENT (line 14) | const INDENT: &str = " ";
type LuaValueId (line 20) | pub(crate) struct LuaValueId(usize);
method from (line 23) | fn from(value: &LuaValue) -> Self {
method from (line 29) | fn from(table: &LuaTable) -> Self {
function format_value_recursive (line 41) | pub(crate) fn format_value_recursive(
function sort_for_formatting (line 103) | fn sort_for_formatting(values: &mut [(LuaValue, LuaValue)]) {
function format_array (line 122) | fn format_array(
function format_table (line 141) | fn format_table(
function format_typename_and_tostringed (line 174) | fn format_typename_and_tostringed(
FILE: crates/lune-utils/src/path/constants.rs
constant FILE_CHUNK_PREFIX (line 5) | pub const FILE_CHUNK_PREFIX: char = '@';
constant FILE_NAME_INIT (line 6) | pub const FILE_NAME_INIT: &str = "init";
constant FILE_NAME_CONFIG (line 7) | pub const FILE_NAME_CONFIG: &str = ".luaurc";
constant FILE_EXTENSIONS (line 8) | pub const FILE_EXTENSIONS: [&str; 2] = ["luau", "lua"];
FILE: crates/lune-utils/src/path/luau.rs
type LuauFilePath (line 23) | pub enum LuauFilePath {
method resolve (line 31) | fn resolve(module: impl AsRef<Path>) -> Result<Self, LuaNavigateError> {
method is_file (line 75) | pub const fn is_file(&self) -> bool {
method is_dir (line 80) | pub const fn is_dir(&self) -> bool {
method as_file (line 85) | pub fn as_file(&self) -> Option<&Path> {
method as_dir (line 93) | pub fn as_dir(&self) -> Option<&Path> {
method as_ref (line 102) | fn as_ref(&self) -> &Path {
method fmt (line 110) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type LuauModulePath (line 129) | pub struct LuauModulePath {
method strip (line 147) | pub fn strip(path: impl Into<PathBuf>) -> PathBuf {
method resolve (line 187) | pub fn resolve(module: impl Into<PathBuf>) -> Result<Self, LuaNavigate...
method source (line 197) | pub fn source(&self) -> &Path {
method target (line 205) | pub fn target(&self) -> &LuauFilePath {
method fmt (line 211) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
FILE: crates/lune-utils/src/path/std.rs
function create_cwd (line 17) | fn create_cwd() -> Arc<Path> {
function create_exe (line 31) | fn create_exe() -> Arc<Path> {
function get_current_dir (line 54) | pub fn get_current_dir() -> Arc<Path> {
function get_current_exe (line 69) | pub fn get_current_exe() -> Arc<Path> {
function clean_path (line 79) | pub fn clean_path(path: impl AsRef<Path>) -> PathBuf {
function clean_path_and_make_absolute (line 91) | pub fn clean_path_and_make_absolute(path: impl AsRef<Path>) -> PathBuf {
function append_extension (line 106) | pub fn append_extension(path: impl AsRef<Path>, ext: impl AsRef<OsStr>) ...
function relative_path_normalize (line 126) | pub fn relative_path_normalize(path: impl AsRef<Path>) -> PathBuf {
function relative_path_parent (line 144) | pub fn relative_path_parent(rel: &mut PathBuf) {
FILE: crates/lune-utils/src/process/args.rs
type ProcessArgsInner (line 15) | struct ProcessArgsInner {
method from_iter (line 20) | fn from_iter<T: IntoIterator<Item = OsString>>(iter: T) -> Self {
type ProcessArgs (line 39) | pub struct ProcessArgs {
method empty (line 45) | pub fn empty() -> Self {
method current (line 52) | pub fn current() -> Self {
method len (line 59) | pub fn len(&self) -> usize {
method is_empty (line 65) | pub fn is_empty(&self) -> bool {
method all (line 73) | pub fn all(&self) -> Vec<OsString> {
method get (line 79) | pub fn get(&self, index: usize) -> Option<OsString> {
method set (line 84) | pub fn set(&self, index: usize, val: impl Into<OsString>) {
method push (line 91) | pub fn push(&self, val: impl Into<OsString>) {
method pop (line 97) | pub fn pop(&self) -> Option<OsString> {
method insert (line 102) | pub fn insert(&self, index: usize, val: impl Into<OsString>) {
method remove (line 110) | pub fn remove(&self, index: usize) -> Option<OsString> {
method all_bytes (line 122) | pub fn all_bytes(&self) -> Vec<Vec<u8>> {
method get_bytes (line 130) | pub fn get_bytes(&self, index: usize) -> Option<Vec<u8>> {
method set_bytes (line 135) | pub fn set_bytes(&self, index: usize, val: impl Into<Vec<u8>>) {
method push_bytes (line 141) | pub fn push_bytes(&self, val: impl Into<Vec<u8>>) {
method pop_bytes (line 148) | pub fn pop_bytes(&self) -> Option<Vec<u8>> {
method insert_bytes (line 152) | pub fn insert_bytes(&self, index: usize, val: impl Into<Vec<u8>>) {
method remove_bytes (line 158) | pub fn remove_bytes(&self, index: usize) -> Option<Vec<u8>> {
method into_plain_lua_table (line 166) | pub fn into_plain_lua_table(&self, lua: Lua) -> LuaResult<LuaTable> {
method from_iter (line 192) | fn from_iter<T: IntoIterator<Item = S>>(iter: T) -> Self {
method extend (line 200) | fn extend<T: IntoIterator<Item = S>>(&mut self, iter: T) {
type Item (line 182) | type Item = OsString;
type IntoIter (line 183) | type IntoIter = std::vec::IntoIter<OsString>;
method into_iter (line 185) | fn into_iter(self) -> Self::IntoIter {
method from_lua (line 209) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
method add_methods (line 241) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
FILE: crates/lune-utils/src/process/env.rs
type ProcessEnvInner (line 16) | struct ProcessEnvInner {
method from_iter (line 21) | fn from_iter<T: IntoIterator<Item = (OsString, OsString)>>(iter: T) ->...
type ProcessEnv (line 40) | pub struct ProcessEnv {
method empty (line 46) | pub fn empty() -> Self {
method current (line 53) | pub fn current() -> Self {
method len (line 60) | pub fn len(&self) -> usize {
method is_empty (line 66) | pub fn is_empty(&self) -> bool {
method get_all (line 74) | pub fn get_all(&self) -> Vec<(OsString, OsString)> {
method get_value (line 80) | pub fn get_value(&self, key: impl AsRef<OsStr>) -> Option<OsString> {
method set_value (line 89) | pub fn set_value(&self, key: impl Into<OsString>, val: impl Into<OsStr...
method remove_value (line 101) | pub fn remove_value(&self, key: impl AsRef<OsStr>) {
method get_all_bytes (line 115) | pub fn get_all_bytes(&self) -> Vec<(Vec<u8>, Vec<u8>)> {
method get_value_bytes (line 123) | pub fn get_value_bytes(&self, key: impl AsRef<[u8]>) -> Option<Vec<u8>> {
method set_value_bytes (line 129) | pub fn set_value_bytes(&self, key: impl AsRef<[u8]>, val: impl Into<Ve...
method remove_value_bytes (line 137) | pub fn remove_value_bytes(&self, key: impl AsRef<[u8]>) {
method into_plain_lua_table (line 148) | pub fn into_plain_lua_table(&self, lua: Lua) -> LuaResult<LuaTable> {
method from_iter (line 175) | fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
method extend (line 188) | fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
type Item (line 165) | type Item = (OsString, OsString);
type IntoIter (line 166) | type IntoIter = std::collections::btree_map::IntoIter<OsString, OsString>;
method into_iter (line 168) | fn into_iter(self) -> Self::IntoIter {
method from_lua (line 201) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
method add_methods (line 238) | fn add_methods<M: LuaUserDataMethods<Self>>(methods: &mut M) {
FILE: crates/lune-utils/src/process/jit.rs
type ProcessJitEnablement (line 2) | pub struct ProcessJitEnablement {
method new (line 8) | pub fn new(enabled: bool) -> Self {
method set_status (line 12) | pub fn set_status(&mut self, enabled: bool) {
method enabled (line 17) | pub fn enabled(self) -> bool {
method from (line 29) | fn from(val: bool) -> Self {
function from (line 23) | fn from(val: ProcessJitEnablement) -> Self {
FILE: crates/lune-utils/src/process/mod.rs
function lua_value_to_os_string (line 14) | fn lua_value_to_os_string(res: LuaResult<LuaValue>, to: &'static str) ->...
function validate_os_key (line 44) | fn validate_os_key(key: &OsStr) -> LuaResult<()> {
function validate_os_value (line 61) | fn validate_os_value(val: &OsStr) -> LuaResult<()> {
function validate_os_pair (line 74) | fn validate_os_pair((key, value): (&OsStr, &OsStr)) -> LuaResult<()> {
FILE: crates/lune-utils/src/table_builder.rs
type TableBuilder (line 10) | pub struct TableBuilder {
method new (line 19) | pub fn new(lua: Lua) -> LuaResult<Self> {
method with_value (line 29) | pub fn with_value<K, V>(self, key: K, value: V) -> LuaResult<Self>
method with_values (line 43) | pub fn with_values<K, V>(self, values: Vec<(K, V)>) -> LuaResult<Self>
method with_sequential_value (line 60) | pub fn with_sequential_value<V>(self, value: V) -> LuaResult<Self>
method with_sequential_values (line 74) | pub fn with_sequential_values<V>(self, values: Vec<V>) -> LuaResult<Self>
method with_function (line 89) | pub fn with_function<K, A, R, F>(self, key: K, func: F) -> LuaResult<S...
method with_async_function (line 105) | pub fn with_async_function<K, A, R, F, FR>(self, key: K, func: F) -> L...
method with_metatable (line 122) | pub fn with_metatable(self, table: LuaTable) -> LuaResult<Self> {
method build_readonly (line 132) | pub fn build_readonly(self) -> LuaResult<LuaTable> {
method build (line 140) | pub fn build(self) -> LuaResult<LuaTable> {
FILE: crates/lune-utils/src/version_string.rs
function get_version_string (line 19) | pub fn get_version_string(lune_version: impl AsRef<str>) -> String {
function create_luau_version_string (line 29) | fn create_luau_version_string() -> Arc<String> {
function is_valid_version_char (line 71) | fn is_valid_version_char(c: char) -> bool {
FILE: crates/lune/src/cli/build/base_exe.rs
constant RELEASE_REQUEST_HEADERS (line 17) | const RELEASE_REQUEST_HEADERS: &[(&str, &str)] = &[
function get_or_download_base_executable (line 39) | pub async fn get_or_download_base_executable(target: BuildTarget) -> Bui...
FILE: crates/lune/src/cli/build/files.rs
function remove_source_file_ext (line 12) | pub fn remove_source_file_ext(path: &Path) -> PathBuf {
function write_executable_file_to (line 27) | pub async fn write_executable_file_to(
FILE: crates/lune/src/cli/build/mod.rs
type BuildCommand (line 21) | pub struct BuildCommand {
method run (line 37) | pub async fn run(self) -> Result<ExitCode> {
FILE: crates/lune/src/cli/build/result.rs
type BuildError (line 9) | pub enum BuildError {
type BuildResult (line 22) | pub type BuildResult<T, E = BuildError> = std::result::Result<T, E>;
FILE: crates/lune/src/cli/build/target.rs
type BuildTargetOS (line 18) | pub enum BuildTargetOS {
method current_system (line 25) | fn current_system() -> Self {
method exe_extension (line 34) | fn exe_extension(self) -> &'static str {
method exe_suffix (line 43) | fn exe_suffix(self) -> &'static str {
method fmt (line 52) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type Err (line 62) | type Err = &'static str;
method from_str (line 63) | fn from_str(s: &str) -> Result<Self, Self::Err> {
type BuildTargetArch (line 77) | pub enum BuildTargetArch {
method current_system (line 83) | fn current_system() -> Self {
method fmt (line 93) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type Err (line 102) | type Err = &'static str;
method from_str (line 103) | fn from_str(s: &str) -> Result<Self, Self::Err> {
type BuildTarget (line 128) | pub struct BuildTarget {
method current_system (line 134) | pub fn current_system() -> Self {
method is_current_system (line 141) | pub fn is_current_system(&self) -> bool {
method exe_extension (line 145) | pub fn exe_extension(&self) -> &'static str {
method exe_suffix (line 149) | pub fn exe_suffix(&self) -> &'static str {
method cache_path (line 153) | pub fn cache_path(&self) -> PathBuf {
method fmt (line 159) | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
type Err (line 165) | type Err = &'static str;
method from_str (line 166) | fn from_str(s: &str) -> Result<Self, Self::Err> {
FILE: crates/lune/src/cli/list.rs
type ListCommand (line 10) | pub struct ListCommand {}
method run (line 13) | pub async fn run(self) -> Result<ExitCode> {
FILE: crates/lune/src/cli/mod.rs
type CliSubcommand (line 18) | pub enum CliSubcommand {
method default (line 27) | fn default() -> Self {
type Cli (line 35) | pub struct Cli {
method new (line 41) | pub fn new() -> Self {
method run (line 71) | pub async fn run(self) -> Result<ExitCode> {
FILE: crates/lune/src/cli/repl.rs
constant MESSAGE_WELCOME (line 11) | const MESSAGE_WELCOME: &str = concat!("Lune v", env!("CARGO_PKG_VERSION"));
constant MESSAGE_INTERRUPT (line 12) | const MESSAGE_INTERRUPT: &str = "Interrupt: ^C again to exit";
type PromptState (line 14) | enum PromptState {
type ReplCommand (line 21) | pub struct ReplCommand {}
method run (line 24) | pub async fn run(self) -> Result<ExitCode> {
FILE: crates/lune/src/cli/run.rs
type RunCommand (line 14) | pub struct RunCommand {
method run (line 22) | pub async fn run(self) -> Result<ExitCode> {
FILE: crates/lune/src/cli/setup.rs
constant LUAURC_PATH (line 11) | const LUAURC_PATH: &str = ".luaurc";
type SetupCommand (line 15) | pub struct SetupCommand {}
method run (line 18) | pub async fn run(self) -> Result<ExitCode> {
type SetupError (line 40) | enum SetupError {
function lune_version (line 51) | fn lune_version() -> &'static str {
function read_or_create_luaurc (line 55) | async fn read_or_create_luaurc() -> Result<JsonValue, SetupError> {
function write_luaurc (line 69) | async fn write_luaurc(luaurc: JsonValue) -> Result<(), SetupError> {
function add_values_to_luaurc (line 82) | fn add_values_to_luaurc(luaurc: &mut JsonValue) {
function generate_typedef_files_from_definitions (line 104) | async fn generate_typedef_files_from_definitions() -> Result<String> {
FILE: crates/lune/src/cli/utils/files.rs
constant LUNE_COMMENT_PREFIX (line 9) | const LUNE_COMMENT_PREFIX: &str = "-->";
function discover_script_path (line 17) | pub fn discover_script_path(path: impl Into<PathBuf>, in_home_dir: bool)...
function discover_script_path_including_lune_dirs (line 64) | pub fn discover_script_path_including_lune_dirs(path: impl AsRef<Path>) ...
function parse_lune_description_from_file (line 93) | pub fn parse_lune_description_from_file(contents: &str) -> Option<String> {
FILE: crates/lune/src/cli/utils/listing.rs
function find_lune_scripts (line 18) | pub async fn find_lune_scripts(in_home_dir: bool) -> Result<Vec<(String,...
function sort_lune_scripts (line 92) | pub fn sort_lune_scripts(scripts: Vec<(String, String)>) -> Vec<(String,...
function write_lune_scripts_list (line 111) | pub fn write_lune_scripts_list(buffer: &mut String, scripts: Vec<(String...
FILE: crates/lune/src/main.rs
function main (line 12) | fn main() -> ExitCode {
FILE: crates/lune/src/rt/result.rs
type RuntimeResult (line 10) | pub type RuntimeResult<T, E = RuntimeError> = Result<T, E>;
type RuntimeError (line 16) | pub struct RuntimeError {
method enable_colors (line 29) | pub fn enable_colors(mut self) -> Self {
method disable_colors (line 41) | pub fn disable_colors(mut self) -> Self {
method is_incomplete_input (line 52) | pub fn is_incomplete_input(&self) -> bool {
method from (line 64) | fn from(value: LuaError) -> Self {
method from (line 73) | fn from(value: &LuaError) -> Self {
method fmt (line 82) | fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
method cause (line 88) | fn cause(&self) -> Option<&dyn Error> {
FILE: crates/lune/src/rt/runtime.rs
type RuntimeReturnValues (line 27) | pub struct RuntimeReturnValues {
method status (line 48) | pub fn status(&self) -> u8 {
method success (line 58) | pub fn success(&self) -> bool {
type Runtime (line 66) | pub struct Runtime {
method new (line 85) | pub fn new() -> LuaResult<Self> {
method with_args (line 156) | pub fn with_args<A, S>(mut self, args: A) -> Self
method with_env (line 171) | pub fn with_env<E, K, V>(mut self, env: E) -> Self
method with_jit (line 185) | pub fn with_jit<J>(mut self, jit_status: J) -> Self
method with_lib (line 231) | pub fn with_lib<S, F>(self, name: S, make_lib: F) -> RuntimeResult<Self>
method run_custom (line 273) | pub async fn run_custom(
method run_file (line 292) | pub async fn run_file(
method run_inner (line 335) | async fn run_inner(
function strip_shebang (line 398) | fn strip_shebang(mut contents: Vec<u8>) -> Vec<u8> {
FILE: crates/lune/src/standalone/metadata.rs
constant MAGIC (line 9) | const MAGIC: &[u8; 8] = b"cr3sc3nt";
type Metadata (line 30) | pub struct Metadata {
method check_env (line 39) | pub async fn check_env() -> (bool, Vec<u8>) {
method create_env_patched_bin (line 50) | pub async fn create_env_patched_bin(
method from_bytes (line 74) | pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result<Self> {
method to_bytes (line 94) | pub fn to_bytes(&self) -> Vec<u8> {
FILE: crates/lune/src/standalone/mod.rs
function check (line 15) | pub async fn check() -> Option<Vec<u8>> {
function run (line 27) | pub async fn run(patched_bin: impl AsRef<[u8]>) -> Result<ExitCode> {
FILE: crates/lune/src/tests.rs
constant ARGS (line 13) | const ARGS: &[&str] = &["Foo", "Bar"];
function run_test (line 15) | fn run_test(path: &str) -> Result<ExitCode> {
FILE: crates/mlua-luau-scheduler/examples/basic_sleep.rs
constant MAIN_SCRIPT (line 12) | const MAIN_SCRIPT: &str = include_str!("./lua/basic_sleep.luau");
function main (line 14) | pub fn main() -> LuaResult<()> {
function test_basic_sleep (line 48) | fn test_basic_sleep() -> LuaResult<()> {
FILE: crates/mlua-luau-scheduler/examples/basic_spawn.rs
constant MAIN_SCRIPT (line 12) | const MAIN_SCRIPT: &str = include_str!("./lua/basic_spawn.luau");
function main (line 14) | pub fn main() -> LuaResult<()> {
function test_basic_spawn (line 62) | fn test_basic_spawn() -> LuaResult<()> {
FILE: crates/mlua-luau-scheduler/examples/callbacks.rs
constant MAIN_SCRIPT (line 10) | const MAIN_SCRIPT: &str = include_str!("./lua/callbacks.luau");
function main (line 12) | pub fn main() -> LuaResult<()> {
function test_callbacks (line 46) | fn test_callbacks() -> LuaResult<()> {
FILE: crates/mlua-luau-scheduler/examples/exit_code.rs
constant MAIN_SCRIPT (line 10) | const MAIN_SCRIPT: &str = include_str!("./lua/exit_code.luau");
function main (line 12) | pub fn main() -> LuaResult<()> {
function test_exit_code (line 41) | fn test_exit_code() -> LuaResult<()> {
FILE: crates/mlua-luau-scheduler/examples/lots_of_threads.rs
constant MAIN_SCRIPT (line 12) | const MAIN_SCRIPT: &str = include_str!("./lua/lots_of_threads.luau");
constant ONE_NANOSECOND (line 14) | const ONE_NANOSECOND: Duration = Duration::from_nanos(1);
function main (line 16) | pub fn main() -> LuaResult<()> {
function test_lots_of_threads (line 53) | fn test_lots_of_threads() -> LuaResult<()> {
FILE: crates/mlua-luau-scheduler/examples/scheduler_ordering.rs
constant MAIN_SCRIPT (line 12) | const MAIN_SCRIPT: &str = include_str!("./lua/scheduler_ordering.luau");
function main (line 14) | pub fn main() -> LuaResult<()> {
function test_scheduler_ordering (line 54) | fn test_scheduler_ordering() -> LuaResult<()> {
FILE: crates/mlua-luau-scheduler/examples/tracy.rs
constant MAIN_SCRIPT (line 27) | const MAIN_SCRIPT: &str = include_str!("./lua/lots_of_threads.luau");
constant ONE_NANOSECOND (line 29) | const ONE_NANOSECOND: Duration = Duration::from_nanos(1);
function main (line 31) | pub fn main() -> LuaResult<()> {
FILE: crates/mlua-luau-scheduler/src/error_callback.rs
type ErrorCallback (line 5) | type ErrorCallback = Box<dyn Fn(LuaError) + Send + 'static>;
type ThreadErrorCallback (line 8) | pub(crate) struct ThreadErrorCallback {
method new (line 13) | pub fn new() -> Self {
method replace (line 19) | pub fn replace(&self, callback: impl Fn(LuaError) + Send + 'static) {
method clear (line 23) | pub fn clear(&self) {
method call (line 27) | pub fn call(&self, error: &LuaError) {
function default_error_callback (line 35) | fn default_error_callback(e: LuaError) {
method default (line 40) | fn default() -> Self {
FILE: crates/mlua-luau-scheduler/src/events/multi.rs
type MultiEventState (line 14) | struct MultiEventState {
type MultiEvent (line 23) | pub(crate) struct MultiEvent {
method new (line 31) | pub fn new() -> Self {
method notify (line 38) | pub fn notify(&self) {
method listen (line 54) | pub fn listen(&self) -> MultiListener {
type MultiListener (line 66) | pub(crate) struct MultiListener {
type Output (line 72) | type Output = ();
method poll (line 74) | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
FILE: crates/mlua-luau-scheduler/src/events/once.rs
type OnceEventState (line 15) | struct OnceEventState {
method new (line 20) | fn new() -> Self {
type OnceEvent (line 33) | pub struct OnceEvent {
method new (line 41) | pub fn new() -> Self {
method notify (line 53) | pub fn notify(&self) {
method listen (line 66) | pub fn listen(&self) -> OnceListener {
type OnceListener (line 81) | pub struct OnceListener {
type Output (line 86) | type Output = ();
method poll (line 88) | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
FILE: crates/mlua-luau-scheduler/src/exit.rs
type Exit (line 6) | pub(crate) struct Exit {
method new (line 12) | pub fn new() -> Self {
method set (line 19) | pub fn set(&self, code: u8) {
method get (line 24) | pub fn get(&self) -> Option<u8> {
method listen (line 28) | pub async fn listen(&self) {
FILE: crates/mlua-luau-scheduler/src/functions.rs
constant ERR_METADATA_NOT_ATTACHED (line 13) | const ERR_METADATA_NOT_ATTACHED: &str = "\
constant EXIT_IMPL_LUA (line 19) | const EXIT_IMPL_LUA: &str = r"
constant WRAP_IMPL_LUA (line 24) | const WRAP_IMPL_LUA: &str = r"
type Functions (line 42) | pub struct Functions {
method new (line 91) | pub fn new(lua: Lua) -> LuaResult<Self> {
method inject_compat (line 268) | pub fn inject_compat(&self, lua: &Lua) -> LuaResult<()> {
FILE: crates/mlua-luau-scheduler/src/queue/deferred.rs
type DeferredThreadQueue (line 9) | pub(crate) struct DeferredThreadQueue(ThreadQueue);
method new (line 12) | pub fn new() -> Self {
type Target (line 18) | type Target = ThreadQueue;
method deref (line 19) | fn deref(&self) -> &Self::Target {
method deref_mut (line 25) | fn deref_mut(&mut self) -> &mut Self::Target {
FILE: crates/mlua-luau-scheduler/src/queue/futures.rs
type LocalBoxFuture (line 7) | pub type LocalBoxFuture<'fut> = Pin<Box<dyn Future<Output = ()> + 'fut>>;
type FuturesQueueInner (line 9) | struct FuturesQueueInner<'fut> {
function new (line 15) | pub fn new() -> Self {
type FuturesQueue (line 30) | pub(crate) struct FuturesQueue<'fut> {
function new (line 35) | pub fn new() -> Self {
function push_item (line 40) | pub fn push_item(&self, fut: impl Future<Output = ()> + 'fut) {
function take_items (line 45) | pub fn take_items(&self) -> Vec<LocalBoxFuture<'fut>> {
function wait_for_item (line 50) | pub async fn wait_for_item(&self) {
FILE: crates/mlua-luau-scheduler/src/queue/spawned.rs
type SpawnedThreadQueue (line 9) | pub(crate) struct SpawnedThreadQueue(ThreadQueue);
method new (line 12) | pub fn new() -> Self {
type Target (line 18) | type Target = ThreadQueue;
method deref (line 19) | fn deref(&self) -> &Self::Target {
method deref_mut (line 25) | fn deref_mut(&mut self) -> &mut Self::Target {
FILE: crates/mlua-luau-scheduler/src/queue/threads.rs
type ThreadQueueInner (line 12) | struct ThreadQueueInner {
method new (line 18) | fn new() -> Self {
type ThreadQueue (line 33) | pub(crate) struct ThreadQueue {
method new (line 38) | pub fn new() -> Self {
method push_item (line 43) | pub fn push_item(
method take_items (line 62) | pub fn take_items(&self) -> Vec<(LuaThread, LuaMultiValue)> {
method wait_for_item (line 68) | pub async fn wait_for_item(&self) {
method is_empty (line 75) | pub fn is_empty(&self) -> bool {
FILE: crates/mlua-luau-scheduler/src/scheduler.rs
constant ERR_METADATA_ALREADY_ATTACHED (line 26) | const ERR_METADATA_ALREADY_ATTACHED: &str = "\
constant ERR_METADATA_REMOVED (line 32) | const ERR_METADATA_REMOVED: &str = "\
constant ERR_SET_CALLBACK_WHEN_RUNNING (line 37) | const ERR_SET_CALLBACK_WHEN_RUNNING: &str = "\
type Scheduler (line 45) | pub struct Scheduler {
method new (line 66) | pub fn new(lua: Lua) -> Scheduler {
method set_status (line 116) | fn set_status(&self, status: Status) {
method status (line 125) | pub fn status(&self) -> Status {
method set_error_callback (line 140) | pub fn set_error_callback(&self, callback: impl Fn(LuaError) + Send + ...
method remove_error_callback (line 157) | pub fn remove_error_callback(&self) {
method get_exit_code (line 169) | pub fn get_exit_code(&self) -> Option<u8> {
method set_exit_code (line 178) | pub fn set_exit_code(&self, code: u8) {
method push_thread_front (line 197) | pub fn push_thread_front(
method push_thread_back (line 224) | pub fn push_thread_back(
method get_thread_result (line 249) | pub fn get_thread_result(&self, id: ThreadId) -> Option<LuaResult<LuaM...
method wait_for_thread (line 258) | pub async fn wait_for_thread(&self, id: ThreadId) {
method run (line 276) | pub async fn run(&self) {
method drop (line 459) | fn drop(&mut self) {
FILE: crates/mlua-luau-scheduler/src/status.rs
type Status (line 7) | pub enum Status {
method is_not_started (line 18) | pub const fn is_not_started(self) -> bool {
method is_running (line 23) | pub const fn is_running(self) -> bool {
method is_completed (line 28) | pub const fn is_completed(self) -> bool {
FILE: crates/mlua-luau-scheduler/src/threads/id.rs
type ThreadId (line 17) | pub struct ThreadId {
method from (line 22) | fn from(thread: &LuaThread) -> Self {
method hash (line 30) | fn hash<H: Hasher>(&self, state: &mut H) {
FILE: crates/mlua-luau-scheduler/src/threads/map.rs
type ThreadEvent (line 12) | struct ThreadEvent {
method new (line 18) | fn new() -> Self {
type ThreadMap (line 27) | pub(crate) struct ThreadMap {
method new (line 32) | pub fn new() -> Self {
method track (line 38) | pub fn track(&self, id: ThreadId) {
method is_tracked (line 43) | pub fn is_tracked(&self, id: ThreadId) -> bool {
method insert (line 48) | pub fn insert(&self, id: ThreadId, result: LuaResult<LuaMultiValue>) {
method listen (line 58) | pub fn listen(&self, id: ThreadId) -> OnceListener {
method remove (line 67) | pub fn remove(&self, id: ThreadId) -> Option<LuaResult<LuaMultiValue>> {
FILE: crates/mlua-luau-scheduler/src/traits.rs
type IntoLuaThread (line 27) | pub trait IntoLuaThread {
method into_lua_thread (line 35) | fn into_lua_thread(self, lua: &Lua) -> LuaResult<LuaThread>;
method into_lua_thread (line 39) | fn into_lua_thread(self, _: &Lua) -> LuaResult<LuaThread> {
method into_lua_thread (line 45) | fn into_lua_thread(self, lua: &Lua) -> LuaResult<LuaThread> {
method into_lua_thread (line 51) | fn into_lua_thread(self, lua: &Lua) -> LuaResult<LuaThread> {
method into_lua_thread (line 60) | fn into_lua_thread(self, lua: &Lua) -> LuaResult<LuaThread> {
type LuaSchedulerExt (line 74) | pub trait LuaSchedulerExt {
method set_exit_code (line 84) | fn set_exit_code(&self, code: u8);
method push_thread_front (line 95) | fn push_thread_front(
method push_thread_back (line 110) | fn push_thread_back(
method track_thread (line 121) | fn track_thread(&self, id: ThreadId);
method get_thread_result (line 132) | fn get_thread_result(&self, id: ThreadId) -> Option<LuaResult<LuaMulti...
method wait_for_thread (line 143) | fn wait_for_thread(&self, id: ThreadId) -> impl Future<Output = ()>;
method set_exit_code (line 285) | fn set_exit_code(&self, code: u8) {
method push_thread_front (line 292) | fn push_thread_front(
method push_thread_back (line 303) | fn push_thread_back(
method track_thread (line 314) | fn track_thread(&self, id: ThreadId) {
method get_thread_result (line 321) | fn get_thread_result(&self, id: ThreadId) -> Option<LuaResult<LuaMulti...
method wait_for_thread (line 328) | fn wait_for_thread(&self, id: ThreadId) -> impl Future<Output = ()> {
type LuaSpawnExt (line 155) | pub trait LuaSpawnExt {
method spawn (line 192) | fn spawn<F, T>(&self, fut: F) -> Task<T>
method spawn_local (line 236) | fn spawn_local<F>(&self, fut: F)
method spawn_blocking (line 278) | fn spawn_blocking<F, T>(&self, f: F) -> Task<T>
method spawn (line 337) | fn spawn<F, T>(&self, fut: F) -> Task<T>
method spawn_local (line 351) | fn spawn_local<F>(&self, fut: F)
method spawn_blocking (line 362) | fn spawn_blocking<F, T>(&self, f: F) -> Task<T>
FILE: crates/mlua-luau-scheduler/src/util.rs
function run_until_yield (line 13) | pub(crate) async fn run_until_yield(
function is_poll_pending (line 37) | pub(crate) fn is_poll_pending(value: &LuaValue) -> bool {
type LuaThreadOrFunction (line 49) | pub(crate) enum LuaThreadOrFunction {
method into_thread (line 55) | pub(super) fn into_thread(self, lua: &Lua) -> LuaResult<LuaThread> {
method from_lua (line 64) | fn from_lua(value: LuaValue, _: &Lua) -> LuaResult<Self> {
Condensed preview — 457 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,201K chars).
[
{
"path": ".cargo/config.toml",
"chars": 683,
"preview": "# Statically link the vcruntime\n# https://users.rust-lang.org/t/static-vcruntime-distribute-windows-msvc-binaries-withou"
},
{
"path": ".editorconfig",
"chars": 227,
"preview": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[*.{json,"
},
{
"path": ".gitattributes",
"chars": 137,
"preview": "* text=auto\n\n# Ensure all lua files use LF\n*.lua eol=lf\n*.luau eol=lf\n\n# Ensure all txt files within tests use LF\ntests"
},
{
"path": ".github/workflows/ci.yaml",
"chars": 2614,
"preview": "name: CI\n\non:\n push:\n pull_request:\n workflow_dispatch:\n\ndefaults:\n run:\n shell: bash\n\nenv:\n CARGO_TERM_COLOR: a"
},
{
"path": ".github/workflows/release.yaml",
"chars": 4153,
"preview": "name: Release\n\non:\n workflow_dispatch:\n\npermissions:\n contents: write\n\ndefaults:\n run:\n shell: bash\n\njobs:\n init:"
},
{
"path": ".gitignore",
"chars": 400,
"preview": "# Annoying macOS finder stuff\n\n/.DS_Store\n/**/.DS_Store\n\n# Autogenerated dirs\n\n/bin\n/out\n/target\n/staging\n\n/**/bin\n/**/o"
},
{
"path": ".gitmodules",
"chars": 128,
"preview": "[submodule \"tests/roblox/rbx-test-files\"]\n\tpath = tests/roblox/rbx-test-files\n\turl = https://github.com/rojo-rbx/rbx-tes"
},
{
"path": ".luaurc",
"chars": 251,
"preview": "{\n \"languageMode\": \"strict\",\n \"lint\": {\n \"*\": true\n },\n \"lintErrors\": false,\n \"typeErrors\": true,\n \"globals\": ["
},
{
"path": ".lune/csv_printer.luau",
"chars": 1792,
"preview": "--> A utility script that prints out a CSV\n--> file in a prettified format to stdout\n\nlocal LINE_SEPARATOR = \"\\n\"\nlocal "
},
{
"path": ".lune/data/test.csv",
"chars": 56,
"preview": "Header1,Header2,Header3\nHello,World,!\n1,2,3\nFoo,Bar,Baz\n"
},
{
"path": ".lune/hello_lune.luau",
"chars": 5341,
"preview": "local fs = require(\"@lune/fs\")\nlocal net = require(\"@lune/net\")\nlocal process = require(\"@lune/process\")\nlocal serde = r"
},
{
"path": ".lune/http_server.luau",
"chars": 1216,
"preview": "--> A basic http server that echoes the given request\n--> body at /ping and otherwise responds 404 \"Not Found\"\n\nlocal ne"
},
{
"path": ".lune/websocket_client.luau",
"chars": 1198,
"preview": "--> A basic web socket client that communicates with an echo server\n\nlocal net = require(\"@lune/net\")\nlocal process = re"
},
{
"path": ".lune/websocket_server.luau",
"chars": 1005,
"preview": "--> A basic web socket server that echoes given messages\n\nlocal net = require(\"@lune/net\")\nlocal process = require(\"@lun"
},
{
"path": ".vscode/extensions.json",
"chars": 177,
"preview": "{\n \"recommendations\": [\n \"rust-lang.rust-analyzer\",\n \"esbenp.prettier-vscode\",\n \"JohnnyMorganz.s"
},
{
"path": ".vscode/settings.json",
"chars": 639,
"preview": "{\n \"luau-lsp.sourcemap.enabled\": false,\n \"luau-lsp.types.roblox\": false,\n \"luau-lsp.ignoreGlobs\": [\n \"te"
},
{
"path": "CHANGELOG.md",
"chars": 62517,
"preview": "<!-- markdownlint-disable MD023 -->\n<!-- markdownlint-disable MD033 -->\n\n# Changelog\n\nAll notable changes to this projec"
},
{
"path": "CONTRIBUTING.md",
"chars": 4521,
"preview": "<!-- markdownlint-disable MD001 -->\n<!-- markdownlint-disable MD033 -->\n\n# Contributing\n\n---\n\n### Reporting a Bug\n\n- Mak"
},
{
"path": "Cargo.toml",
"chars": 2180,
"preview": "[workspace]\nresolver = \"2\"\ndefault-members = [\"crates/lune\"]\nmembers = [\n \"crates/lune\",\n \"crates/lune-roblox\",\n "
},
{
"path": "LICENSE.txt",
"chars": 16726,
"preview": "Mozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor\""
},
{
"path": "README.md",
"chars": 2289,
"preview": "<!-- markdownlint-disable MD033 -->\n<!-- markdownlint-disable MD041 -->\n\n<img align=\"right\" width=\"250\" src=\"assets/logo"
},
{
"path": "crates/lune/Cargo.toml",
"chars": 2077,
"preview": "[package]\nname = \"lune\"\nversion = \"0.10.4\"\nedition = \"2024\"\nlicense = \"MPL-2.0\"\nrepository = \"https://github.com/lune-or"
},
{
"path": "crates/lune/src/cli/build/base_exe.rs",
"chars": 3867,
"preview": "use std::{\n io::{Cursor, Read},\n path::PathBuf,\n};\n\nuse async_fs as fs;\nuse blocking::unblock;\n\nuse crate::standal"
},
{
"path": "crates/lune/src/cli/build/files.rs",
"chars": 1125,
"preview": "use std::path::{Path, PathBuf};\n\nuse anyhow::Result;\nuse async_fs as fs;\nuse futures_lite::prelude::*;\n\n/**\n Removes "
},
{
"path": "crates/lune/src/cli/build/mod.rs",
"chars": 2977,
"preview": "use std::{path::PathBuf, process::ExitCode};\n\nuse anyhow::{Context, Result, bail};\nuse async_fs as fs;\nuse clap::Parser;"
},
{
"path": "crates/lune/src/cli/build/result.rs",
"chars": 686,
"preview": "use thiserror::Error;\n\nuse super::target::BuildTarget;\n\n/**\n Errors that may occur when building a standalone binary\n"
},
{
"path": "crates/lune/src/cli/build/target.rs",
"chars": 4552,
"preview": "use std::{env::consts::ARCH, fmt, path::PathBuf, str::FromStr, sync::LazyLock};\n\nuse directories::BaseDirs;\n\nstatic HOME"
},
{
"path": "crates/lune/src/cli/list.rs",
"chars": 1562,
"preview": "use std::{fmt::Write as _, process::ExitCode};\n\nuse anyhow::Result;\nuse clap::Parser;\n\nuse super::utils::listing::{find_"
},
{
"path": "crates/lune/src/cli/mod.rs",
"chars": 2204,
"preview": "use std::{env::args_os, process::ExitCode};\n\nuse anyhow::Result;\nuse clap::{Parser, Subcommand};\n\npub(crate) mod build;\n"
},
{
"path": "crates/lune/src/cli/repl.rs",
"chars": 3389,
"preview": "use std::{path::PathBuf, process::ExitCode};\n\nuse anyhow::{Context, Result};\nuse async_fs as fs;\nuse clap::Parser;\nuse d"
},
{
"path": "crates/lune/src/cli/run.rs",
"chars": 1871,
"preview": "use std::{env, io::stdin, process::ExitCode};\n\nuse anyhow::{Context, Result};\nuse blocking::Unblock;\nuse clap::Parser;\nu"
},
{
"path": "crates/lune/src/cli/setup.rs",
"chars": 3998,
"preview": "use std::{io::ErrorKind, process::ExitCode};\n\nuse anyhow::{Context, Result};\nuse async_fs as fs;\nuse clap::Parser;\nuse d"
},
{
"path": "crates/lune/src/cli/utils/files.rs",
"chars": 4377,
"preview": "use std::path::{Path, PathBuf};\n\nuse anyhow::{Context, Result, anyhow};\nuse console::style;\nuse directories::UserDirs;\n\n"
},
{
"path": "crates/lune/src/cli/utils/listing.rs",
"chars": 5864,
"preview": "#![allow(clippy::match_same_arms)]\n\nuse std::{\n cmp::Ordering, ffi::OsStr, fmt::Write as _, io::ErrorKind, path::Path"
},
{
"path": "crates/lune/src/cli/utils/mod.rs",
"chars": 32,
"preview": "pub mod files;\npub mod listing;\n"
},
{
"path": "crates/lune/src/lib.rs",
"chars": 156,
"preview": "#![allow(clippy::cargo_common_metadata)]\n\nmod rt;\n\n#[cfg(test)]\nmod tests;\n\npub use crate::rt::{Runtime, RuntimeError, R"
},
{
"path": "crates/lune/src/main.rs",
"chars": 1117,
"preview": "#![allow(clippy::cargo_common_metadata)]\n\nuse std::{io::stderr, process::ExitCode};\n\n#[cfg(feature = \"cli\")]\npub(crate) "
},
{
"path": "crates/lune/src/rt/mod.rs",
"chars": 134,
"preview": "mod result;\nmod runtime;\n\npub use self::result::{RuntimeError, RuntimeResult};\npub use self::runtime::{Runtime, RuntimeR"
},
{
"path": "crates/lune/src/rt/result.rs",
"chars": 2017,
"preview": "use std::{\n error::Error,\n fmt::{Debug, Display, Formatter, Result as FmtResult},\n};\n\nuse mlua::prelude::*;\n\nuse l"
},
{
"path": "crates/lune/src/rt/runtime.rs",
"chars": 12392,
"preview": "#![allow(clippy::missing_panics_doc)]\n\nuse std::{\n ffi::OsString,\n path::PathBuf,\n sync::{\n Arc,\n "
},
{
"path": "crates/lune/src/standalone/metadata.rs",
"chars": 3246,
"preview": "use std::{env, path::PathBuf, sync::LazyLock};\n\nuse anyhow::{Result, bail};\nuse async_fs as fs;\nuse mlua::Compiler as Lu"
},
{
"path": "crates/lune/src/standalone/mod.rs",
"chars": 1150,
"preview": "use std::{env, process::ExitCode};\n\nuse anyhow::Result;\nuse lune::Runtime;\n\npub(crate) mod metadata;\npub(crate) mod trac"
},
{
"path": "crates/lune/src/standalone/tracer.rs",
"chars": 642,
"preview": "/*\n TODO: Implement tracing of requires here\n\n Rough steps / outline:\n\n 1. Create a new tracer struct using a m"
},
{
"path": "crates/lune/src/tests.rs",
"chars": 10574,
"preview": "use std::env::set_current_dir;\nuse std::path::PathBuf;\nuse std::process::ExitCode;\n\nuse anyhow::Result;\nuse console::set"
},
{
"path": "crates/lune-roblox/Cargo.toml",
"chars": 615,
"preview": "[package]\nname = \"lune-roblox\"\nversion = \"0.3.4\"\nedition = \"2024\"\nlicense = \"MPL-2.0\"\nrepository = \"https://github.com/l"
},
{
"path": "crates/lune-roblox/src/datatypes/attributes.rs",
"chars": 2283,
"preview": "use mlua::prelude::*;\n\nuse rbx_dom_weak::types::{Variant as DomValue, VariantType as DomType};\n\nuse super::extension::Do"
},
{
"path": "crates/lune-roblox/src/datatypes/conversion.rs",
"chars": 17694,
"preview": "use mlua::prelude::*;\n\nuse rbx_dom_weak::types::{Variant as DomValue, VariantType as DomType};\n\nuse crate::{datatypes::e"
},
{
"path": "crates/lune-roblox/src/datatypes/extension.rs",
"chars": 1961,
"preview": "use super::*;\n\npub(crate) trait DomValueExt {\n fn variant_name(&self) -> Option<&'static str>;\n}\n\nimpl DomValueExt fo"
},
{
"path": "crates/lune-roblox/src/datatypes/mod.rs",
"chars": 414,
"preview": "pub(crate) use rbx_dom_weak::types::{Variant as DomValue, VariantType as DomType};\n\npub mod extension;\n\n#[cfg(feature = "
},
{
"path": "crates/lune-roblox/src/datatypes/result.rs",
"chars": 2146,
"preview": "use core::fmt;\n\nuse std::error::Error;\nuse std::io::Error as IoError;\n\n#[cfg(feature = \"mlua\")]\nuse mlua::Error as LuaEr"
},
{
"path": "crates/lune-roblox/src/datatypes/types/axes.rs",
"chars": 4182,
"preview": "use core::fmt;\n\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::Axes as DomAxes;\n\nuse lune_utils::TableBuilder;\n\nuse crat"
},
{
"path": "crates/lune-roblox/src/datatypes/types/brick_color.rs",
"chars": 16741,
"preview": "use core::fmt;\n\nuse mlua::prelude::*;\nuse rand::prelude::*;\nuse rbx_dom_weak::types::BrickColor as DomBrickColor;\n\nuse l"
},
{
"path": "crates/lune-roblox/src/datatypes/types/cframe.rs",
"chars": 17495,
"preview": "#![allow(clippy::items_after_statements)]\n\nuse core::fmt;\nuse std::ops;\n\nuse glam::{EulerRot, Mat3, Mat4, Quat, Vec3};\nu"
},
{
"path": "crates/lune-roblox/src/datatypes/types/color3.rs",
"chars": 9423,
"preview": "#![allow(clippy::many_single_char_names)]\n\nuse core::fmt;\nuse std::ops;\n\nuse glam::Vec3;\nuse mlua::prelude::*;\nuse rbx_d"
},
{
"path": "crates/lune-roblox/src/datatypes/types/color_sequence.rs",
"chars": 4107,
"preview": "use core::fmt;\n\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::{\n ColorSequence as DomColorSequence, ColorSequenceKey"
},
{
"path": "crates/lune-roblox/src/datatypes/types/color_sequence_keypoint.rs",
"chars": 2272,
"preview": "use core::fmt;\n\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::ColorSequenceKeypoint as DomColorSequenceKeypoint;\n\nuse l"
},
{
"path": "crates/lune-roblox/src/datatypes/types/content.rs",
"chars": 4380,
"preview": "use core::fmt;\n\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::{Content as DomContent, ContentType};\n\nuse lune_utils::Ta"
},
{
"path": "crates/lune-roblox/src/datatypes/types/enum.rs",
"chars": 2147,
"preview": "use core::fmt;\n\nuse mlua::prelude::*;\nuse rbx_reflection::EnumDescriptor;\n\nuse super::{super::*, EnumItem};\n\n/**\n An "
},
{
"path": "crates/lune-roblox/src/datatypes/types/enum_item.rs",
"chars": 3547,
"preview": "use core::fmt;\n\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::EnumItem as DomEnumItem;\n\nuse super::{super::*, Enum};\n\n/"
},
{
"path": "crates/lune-roblox/src/datatypes/types/enums.rs",
"chars": 1316,
"preview": "use core::fmt;\n\nuse mlua::prelude::*;\n\nuse super::{super::*, Enum};\n\n/**\n An implementation of the [Enums](https://cr"
},
{
"path": "crates/lune-roblox/src/datatypes/types/faces.rs",
"chars": 4648,
"preview": "#![allow(clippy::struct_excessive_bools)]\n\nuse core::fmt;\n\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::Faces as DomFa"
},
{
"path": "crates/lune-roblox/src/datatypes/types/font.rs",
"chars": 18514,
"preview": "use core::fmt;\nuse std::str::FromStr;\n\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::{\n Font as DomFont, FontStyle a"
},
{
"path": "crates/lune-roblox/src/datatypes/types/mod.rs",
"chars": 1238,
"preview": "mod axes;\nmod brick_color;\nmod cframe;\nmod color3;\nmod color_sequence;\nmod color_sequence_keypoint;\nmod content;\nmod r#e"
},
{
"path": "crates/lune-roblox/src/datatypes/types/number_range.rs",
"chars": 2122,
"preview": "use core::fmt;\n\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::NumberRange as DomNumberRange;\n\nuse lune_utils::TableBuil"
},
{
"path": "crates/lune-roblox/src/datatypes/types/number_sequence.rs",
"chars": 4228,
"preview": "use core::fmt;\n\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::{\n NumberSequence as DomNumberSequence, NumberSequence"
},
{
"path": "crates/lune-roblox/src/datatypes/types/number_sequence_keypoint.rs",
"chars": 2496,
"preview": "use core::fmt;\n\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::NumberSequenceKeypoint as DomNumberSequenceKeypoint;\n\nuse"
},
{
"path": "crates/lune-roblox/src/datatypes/types/physical_properties.rs",
"chars": 8374,
"preview": "use core::fmt;\n\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::CustomPhysicalProperties as DomCustomPhysicalProperties;\n"
},
{
"path": "crates/lune-roblox/src/datatypes/types/ray.rs",
"chars": 2973,
"preview": "use core::fmt;\n\nuse glam::Vec3;\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::Ray as DomRay;\n\nuse lune_utils::TableBuil"
},
{
"path": "crates/lune-roblox/src/datatypes/types/rect.rs",
"chars": 3912,
"preview": "use core::fmt;\nuse std::ops;\n\nuse glam::Vec2;\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::Rect as DomRect;\n\nuse lune_"
},
{
"path": "crates/lune-roblox/src/datatypes/types/region3.rs",
"chars": 2536,
"preview": "use core::fmt;\n\nuse glam::{Mat4, Vec3};\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::Region3 as DomRegion3;\n\nuse lune_"
},
{
"path": "crates/lune-roblox/src/datatypes/types/region3int16.rs",
"chars": 2303,
"preview": "use core::fmt;\n\nuse glam::IVec3;\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::Region3int16 as DomRegion3int16;\n\nuse lu"
},
{
"path": "crates/lune-roblox/src/datatypes/types/udim.rs",
"chars": 3044,
"preview": "use core::fmt;\nuse std::ops;\n\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::UDim as DomUDim;\n\nuse lune_utils::TableBuil"
},
{
"path": "crates/lune-roblox/src/datatypes/types/udim2.rs",
"chars": 5314,
"preview": "#![allow(clippy::items_after_statements)]\n\nuse core::fmt;\nuse std::ops;\n\nuse glam::Vec2;\nuse mlua::prelude::*;\nuse rbx_d"
},
{
"path": "crates/lune-roblox/src/datatypes/types/unique_id.rs",
"chars": 2916,
"preview": "use std::fmt;\n\nuse lune_utils::TableBuilder;\nuse mlua::BString;\nuse mlua::prelude::*;\n\nuse super::super::*;\nuse crate::e"
},
{
"path": "crates/lune-roblox/src/datatypes/types/vector2.rs",
"chars": 5627,
"preview": "use core::fmt;\nuse std::ops;\n\nuse glam::{Vec2, Vec3};\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::Vector2 as DomVecto"
},
{
"path": "crates/lune-roblox/src/datatypes/types/vector2int16.rs",
"chars": 3644,
"preview": "use core::fmt;\nuse std::ops;\n\nuse glam::IVec2;\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::Vector2int16 as DomVector2"
},
{
"path": "crates/lune-roblox/src/datatypes/types/vector3.rs",
"chars": 7975,
"preview": "use core::fmt;\nuse std::ops;\n\nuse glam::Vec3;\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::Vector3 as DomVector3;\n\nuse"
},
{
"path": "crates/lune-roblox/src/datatypes/types/vector3int16.rs",
"chars": 3897,
"preview": "use core::fmt;\nuse std::ops;\n\nuse glam::IVec3;\nuse mlua::prelude::*;\nuse rbx_dom_weak::types::Vector3int16 as DomVector3"
},
{
"path": "crates/lune-roblox/src/datatypes/util.rs",
"chars": 562,
"preview": "// HACK: We round to the nearest Very Small Decimal\n// to reduce writing out floating point accumulation\n// errors to fi"
},
{
"path": "crates/lune-roblox/src/document/error.rs",
"chars": 1042,
"preview": "use thiserror::Error;\n\n#[cfg(feature = \"mlua\")]\nuse mlua::prelude::*;\n\n#[derive(Debug, Clone, Error)]\npub enum DocumentE"
},
{
"path": "crates/lune-roblox/src/document/format.rs",
"chars": 5324,
"preview": "// Original implementation from Remodel:\n// https://github.com/rojo-rbx/remodel/blob/master/src/sniff_type.rs\n\nuse std::"
},
{
"path": "crates/lune-roblox/src/document/kind.rs",
"chars": 5821,
"preview": "use std::path::Path;\n\nuse rbx_dom_weak::WeakDom;\n\nuse crate::shared::instance::class_is_a_service;\n\n/**\n A document k"
},
{
"path": "crates/lune-roblox/src/document/mod.rs",
"chars": 9931,
"preview": "use rbx_dom_weak::{InstanceBuilder as DomInstanceBuilder, WeakDom, types::Ref as DomRef};\nuse rbx_xml::{\n DecodeOptio"
},
{
"path": "crates/lune-roblox/src/document/postprocessing.rs",
"chars": 1513,
"preview": "use rbx_dom_weak::{\n Instance as DomInstance, WeakDom,\n types::{Ref as DomRef, VariantType as DomType},\n ustr,\n"
},
{
"path": "crates/lune-roblox/src/exports.rs",
"chars": 1540,
"preview": "use mlua::prelude::*;\n\n/**\n Trait for any item that should be exported as part of the `roblox` built-in library.\n\n "
},
{
"path": "crates/lune-roblox/src/instance/base.rs",
"chars": 13113,
"preview": "#![allow(clippy::items_after_statements)]\n\nuse mlua::prelude::*;\n\nuse rbx_dom_weak::{\n Instance as DomInstance,\n t"
},
{
"path": "crates/lune-roblox/src/instance/data_model.rs",
"chars": 2510,
"preview": "use mlua::prelude::*;\n\nuse crate::shared::{\n classes::{\n add_class_restricted_getter, add_class_restricted_met"
},
{
"path": "crates/lune-roblox/src/instance/mod.rs",
"chars": 27587,
"preview": "#![allow(clippy::missing_panics_doc)]\n\nuse std::{\n collections::{BTreeMap, VecDeque},\n fmt,\n hash::{Hash, Hashe"
},
{
"path": "crates/lune-roblox/src/instance/registry.rs",
"chars": 8080,
"preview": "use std::{\n borrow::Borrow,\n collections::HashMap,\n sync::{Arc, Mutex},\n};\n\nuse mlua::{AppDataRef, prelude::*};"
},
{
"path": "crates/lune-roblox/src/instance/terrain.rs",
"chars": 2689,
"preview": "use mlua::prelude::*;\nuse rbx_dom_weak::types::{MaterialColors, TerrainMaterials, Variant};\n\nuse crate::{\n datatypes:"
},
{
"path": "crates/lune-roblox/src/instance/workspace.rs",
"chars": 1202,
"preview": "use mlua::prelude::*;\n\nuse crate::shared::classes::{add_class_restricted_getter, get_or_create_property_ref_instance};\n\n"
},
{
"path": "crates/lune-roblox/src/lib.rs",
"chars": 2544,
"preview": "#![allow(clippy::cargo_common_metadata)]\n\n#[cfg(feature = \"mlua\")]\nuse mlua::prelude::*;\n\n#[cfg(feature = \"mlua\")]\nuse l"
},
{
"path": "crates/lune-roblox/src/reflection/class.rs",
"chars": 4963,
"preview": "use core::fmt;\nuse std::collections::HashMap;\n\n#[cfg(feature = \"mlua\")]\nuse mlua::prelude::*;\n\nuse rbx_dom_weak::types::"
},
{
"path": "crates/lune-roblox/src/reflection/enums.rs",
"chars": 1888,
"preview": "use std::{collections::HashMap, fmt};\n\n#[cfg(feature = \"mlua\")]\nuse mlua::prelude::*;\n\nuse rbx_reflection::EnumDescripto"
},
{
"path": "crates/lune-roblox/src/reflection/mod.rs",
"chars": 4434,
"preview": "use std::fmt;\n\n#[cfg(feature = \"mlua\")]\nuse mlua::prelude::*;\n\nuse rbx_reflection::ReflectionDatabase;\n\nmod class;\nmod e"
},
{
"path": "crates/lune-roblox/src/reflection/property.rs",
"chars": 3047,
"preview": "use std::fmt;\n\n#[cfg(feature = \"mlua\")]\nuse mlua::prelude::*;\n\nuse rbx_reflection::{ClassDescriptor, PropertyDescriptor}"
},
{
"path": "crates/lune-roblox/src/reflection/utils.rs",
"chars": 1922,
"preview": "use rbx_reflection::{ClassTag, DataType, PropertyTag, Scriptability};\n\nuse crate::datatypes::extension::DomValueExt;\n\npu"
},
{
"path": "crates/lune-roblox/src/shared/classes.rs",
"chars": 3942,
"preview": "use mlua::prelude::*;\n\nuse rbx_dom_weak::types::Variant as DomValue;\n\nuse crate::instance::Instance;\n\nuse super::instanc"
},
{
"path": "crates/lune-roblox/src/shared/instance.rs",
"chars": 7598,
"preview": "#![allow(dead_code)]\n\nuse std::borrow::{Borrow, BorrowMut, Cow};\n\nuse rbx_dom_weak::types::{Variant as DomValue, Variant"
},
{
"path": "crates/lune-roblox/src/shared/mod.rs",
"chars": 126,
"preview": "pub(crate) mod instance;\n\n#[cfg(feature = \"mlua\")]\npub(crate) mod classes;\n\n#[cfg(feature = \"mlua\")]\npub(crate) mod user"
},
{
"path": "crates/lune-roblox/src/shared/userdata.rs",
"chars": 5902,
"preview": "#![allow(clippy::missing_errors_doc)]\n\nuse std::{any::type_name, cell::RefCell, fmt, ops};\n\nuse mlua::prelude::*;\n\n// Ut"
},
{
"path": "crates/lune-std/Cargo.toml",
"chars": 1859,
"preview": "[package]\nname = \"lune-std\"\nversion = \"0.3.4\"\nedition = \"2024\"\nlicense = \"MPL-2.0\"\nrepository = \"https://github.com/lune"
},
{
"path": "crates/lune-std/src/global.rs",
"chars": 2405,
"preview": "use std::str::FromStr;\n\nuse mlua::prelude::*;\n\n/**\n A standard global provided by Lune.\n*/\n#[derive(Debug, Clone, Cop"
},
{
"path": "crates/lune-std/src/globals/g_table.rs",
"chars": 113,
"preview": "use mlua::prelude::*;\n\npub fn create(lua: Lua) -> LuaResult<LuaValue> {\n lua.create_table()?.into_lua(&lua)\n}\n"
},
{
"path": "crates/lune-std/src/globals/mod.rs",
"chars": 80,
"preview": "pub mod g_table;\npub mod print;\npub mod require;\npub mod version;\npub mod warn;\n"
},
{
"path": "crates/lune-std/src/globals/print.rs",
"chars": 605,
"preview": "use std::io::Write;\n\nuse lune_utils::fmt::{ValueFormatConfig, pretty_format_multi_value};\nuse mlua::prelude::*;\n\nconst F"
},
{
"path": "crates/lune-std/src/globals/require.rs",
"chars": 201,
"preview": "use mlua::prelude::*;\n\nuse crate::require::RequireResolver;\n\npub fn create(lua: Lua) -> LuaResult<LuaValue> {\n lua.cr"
},
{
"path": "crates/lune-std/src/globals/version.rs",
"chars": 1021,
"preview": "use mlua::prelude::*;\n\nuse lune_utils::get_version_string;\n\nstruct Version(String);\n\nimpl LuaUserData for Version {}\n\npu"
},
{
"path": "crates/lune-std/src/globals/warn.rs",
"chars": 675,
"preview": "use std::io::Write;\n\nuse lune_utils::fmt::{Label, ValueFormatConfig, pretty_format_multi_value};\nuse mlua::prelude::*;\n\n"
},
{
"path": "crates/lune-std/src/lib.rs",
"chars": 1110,
"preview": "#![allow(clippy::cargo_common_metadata)]\n\nuse mlua::prelude::*;\n\nmod global;\nmod globals;\nmod library;\nmod require;\n\npub"
},
{
"path": "crates/lune-std/src/library.rs",
"chars": 6173,
"preview": "use std::str::FromStr;\n\nuse mlua::prelude::*;\n\n/**\n A standard library provided by Lune.\n*/\n#[derive(Debug, Clone, Co"
},
{
"path": "crates/lune-std/src/require/loader.rs",
"chars": 3620,
"preview": "use std::{\n cell::RefCell,\n collections::HashMap,\n path::{Path, PathBuf},\n rc::Rc,\n};\n\nuse async_channel::{R"
},
{
"path": "crates/lune-std/src/require/mod.rs",
"chars": 75,
"preview": "mod loader;\nmod resolver;\n\npub(crate) use self::resolver::RequireResolver;\n"
},
{
"path": "crates/lune-std/src/require/resolver.rs",
"chars": 5311,
"preview": "use std::{\n fs::read as read_file,\n io::Result as IoResult,\n path::{Path, PathBuf},\n};\n\nuse lune_utils::path::{"
},
{
"path": "crates/lune-std-datetime/Cargo.toml",
"chars": 426,
"preview": "[package]\nname = \"lune-std-datetime\"\nversion = \"0.3.4\"\nedition = \"2024\"\nlicense = \"MPL-2.0\"\nrepository = \"https://github"
},
{
"path": "crates/lune-std-datetime/src/date_time.rs",
"chars": 9564,
"preview": "use std::cmp::Ordering;\n\nuse mlua::prelude::*;\n\nuse chrono::DateTime as ChronoDateTime;\nuse chrono::prelude::*;\nuse chro"
},
{
"path": "crates/lune-std-datetime/src/lib.rs",
"chars": 1473,
"preview": "#![allow(clippy::cargo_common_metadata)]\n\nuse mlua::prelude::*;\n\nuse lune_utils::TableBuilder;\n\nmod date_time;\nmod resul"
},
{
"path": "crates/lune-std-datetime/src/result.rs",
"chars": 791,
"preview": "use mlua::prelude::*;\n\nuse thiserror::Error;\n\npub type DateTimeResult<T, E = DateTimeError> = Result<T, E>;\n\n#[derive(De"
},
{
"path": "crates/lune-std-datetime/src/values.rs",
"chars": 5000,
"preview": "use mlua::prelude::*;\n\nuse chrono::prelude::*;\n\nuse lune_utils::TableBuilder;\n\nuse super::result::{DateTimeError, DateTi"
},
{
"path": "crates/lune-std-datetime/types.d.luau",
"chars": 14011,
"preview": "--[[\n\tNOTE: We export a couple different DateTimeValues types below to ensure\n\tthat types are completely accurate, for m"
},
{
"path": "crates/lune-std-fs/Cargo.toml",
"chars": 482,
"preview": "[package]\nname = \"lune-std-fs\"\nversion = \"0.3.4\"\nedition = \"2024\"\nlicense = \"MPL-2.0\"\nrepository = \"https://github.com/l"
},
{
"path": "crates/lune-std-fs/src/copy.rs",
"chars": 5617,
"preview": "use std::collections::VecDeque;\nuse std::io::ErrorKind;\nuse std::path::{Path, PathBuf};\n\nuse async_fs as fs;\nuse futures"
},
{
"path": "crates/lune-std-fs/src/lib.rs",
"chars": 4267,
"preview": "#![allow(clippy::cargo_common_metadata)]\n\nuse std::io::ErrorKind as IoErrorKind;\nuse std::path::PathBuf;\n\nuse async_fs a"
},
{
"path": "crates/lune-std-fs/src/metadata.rs",
"chars": 4077,
"preview": "use std::{\n fmt,\n fs::{FileType as StdFileType, Metadata as StdMetadata, Permissions as StdPermissions},\n io::R"
},
{
"path": "crates/lune-std-fs/src/options.rs",
"chars": 997,
"preview": "use mlua::prelude::*;\n\n#[derive(Debug, Clone, Copy)]\npub struct FsWriteOptions {\n pub(crate) overwrite: bool,\n}\n\nimpl"
},
{
"path": "crates/lune-std-fs/types.d.luau",
"chars": 7445,
"preview": "--!nocheck\n\nlocal DateTime = require(\"@lune/datetime\")\ntype DateTime = DateTime.DateTime\n\nexport type MetadataKind = \"fi"
},
{
"path": "crates/lune-std-luau/Cargo.toml",
"chars": 373,
"preview": "[package]\nname = \"lune-std-luau\"\nversion = \"0.3.4\"\nedition = \"2024\"\nlicense = \"MPL-2.0\"\nrepository = \"https://github.com"
},
{
"path": "crates/lune-std-luau/src/lib.rs",
"chars": 2798,
"preview": "#![allow(clippy::cargo_common_metadata)]\n\nuse mlua::prelude::*;\n\nuse lune_utils::{TableBuilder, jit::JitEnablement};\n\nmo"
},
{
"path": "crates/lune-std-luau/src/options.rs",
"chars": 4617,
"preview": "#![allow(clippy::struct_field_names)]\n\nuse mlua::Compiler as LuaCompiler;\nuse mlua::prelude::*;\n\nconst DEFAULT_DEBUG_NAM"
},
{
"path": "crates/lune-std-luau/types.d.luau",
"chars": 3509,
"preview": "--[=[\n\t@interface CompileOptions\n\t@within Luau\n\n\tThe options passed to the luau compiler while compiling bytecode.\n\n\tThi"
},
{
"path": "crates/lune-std-net/Cargo.toml",
"chars": 1138,
"preview": "[package]\nname = \"lune-std-net\"\nversion = \"0.3.4\"\nedition = \"2024\"\nlicense = \"MPL-2.0\"\nrepository = \"https://github.com/"
},
{
"path": "crates/lune-std-net/src/body/cursor.rs",
"chars": 1159,
"preview": "use hyper::body::{Buf, Bytes};\n\nuse super::inner::ReadableBodyInner;\n\n/**\n The cursor keeping track of inner data and"
},
{
"path": "crates/lune-std-net/src/body/incoming.rs",
"chars": 910,
"preview": "use http_body_util::BodyExt;\nuse hyper::{\n HeaderMap,\n body::{Bytes, Incoming},\n header::CONTENT_ENCODING,\n};\n\n"
},
{
"path": "crates/lune-std-net/src/body/inner.rs",
"chars": 3492,
"preview": "use hyper::body::{Buf as _, Bytes};\nuse mlua::{Buffer as LuaBuffer, prelude::*};\n\n/**\n The inner data for a readable "
},
{
"path": "crates/lune-std-net/src/body/mod.rs",
"chars": 245,
"preview": "#![allow(unused_imports)]\n\nmod cursor;\nmod incoming;\nmod inner;\nmod readable;\n\npub use self::cursor::ReadableBodyCursor;"
},
{
"path": "crates/lune-std-net/src/body/readable.rs",
"chars": 2643,
"preview": "use std::convert::Infallible;\nuse std::pin::Pin;\nuse std::task::{Context, Poll};\n\nuse hyper::body::{Body, Bytes, Frame, "
},
{
"path": "crates/lune-std-net/src/client/fetch.rs",
"chars": 3815,
"preview": "use std::{collections::HashMap, str::FromStr};\n\nuse async_executor::Executor;\nuse http_body_util::Full;\nuse hyper::{\n "
},
{
"path": "crates/lune-std-net/src/client/mod.rs",
"chars": 2544,
"preview": "use hyper::{Method, Response as HyperResponse, Uri, body::Incoming, header::LOCATION};\n\nuse mlua::prelude::*;\nuse url::U"
},
{
"path": "crates/lune-std-net/src/client/rustls.rs",
"chars": 774,
"preview": "use std::sync::{\n Arc, LazyLock,\n atomic::{AtomicBool, Ordering},\n};\n\nuse rustls::{ClientConfig, crypto::ring};\n\ns"
},
{
"path": "crates/lune-std-net/src/client/send.rs",
"chars": 2508,
"preview": "use http_body_util::Full;\nuse hyper::{\n Method, Request as HyperRequest,\n client::conn::http1::handshake,\n head"
},
{
"path": "crates/lune-std-net/src/client/stream.rs",
"chars": 6597,
"preview": "use std::{\n io::{Error, Result},\n net::SocketAddr,\n pin::Pin,\n sync::Arc,\n task::{Context, Poll},\n};\n\nuse"
},
{
"path": "crates/lune-std-net/src/client/tcp.rs",
"chars": 1038,
"preview": "use mlua::prelude::*;\n\n#[derive(Debug, Default, Clone, Copy)]\npub struct TcpConfig {\n pub tls: Option<bool>,\n pub "
},
{
"path": "crates/lune-std-net/src/lib.rs",
"chars": 2997,
"preview": "#![allow(clippy::cargo_common_metadata)]\n\nuse lune_utils::TableBuilder;\nuse mlua::prelude::*;\n\npub(crate) mod body;\npub("
},
{
"path": "crates/lune-std-net/src/server/config.rs",
"chars": 3271,
"preview": "use std::net::{IpAddr, Ipv4Addr};\n\nuse mlua::prelude::*;\n\nconst DEFAULT_IP_ADDRESS: IpAddr = IpAddr::V4(Ipv4Addr::LOCALH"
},
{
"path": "crates/lune-std-net/src/server/handle.rs",
"chars": 2219,
"preview": "use std::{\n net::SocketAddr,\n sync::{\n Arc,\n atomic::{AtomicBool, Ordering},\n },\n};\n\nuse async_ch"
},
{
"path": "crates/lune-std-net/src/server/mod.rs",
"chars": 4901,
"preview": "use std::{cell::Cell, net::SocketAddr, rc::Rc};\n\nuse async_net::TcpListener;\nuse futures_lite::pin;\nuse hyper::server::c"
},
{
"path": "crates/lune-std-net/src/server/service.rs",
"chars": 3775,
"preview": "use std::{future::Future, net::SocketAddr, pin::Pin};\n\nuse async_tungstenite::{WebSocketStream, tungstenite::protocol::R"
},
{
"path": "crates/lune-std-net/src/server/upgrade.rs",
"chars": 1992,
"preview": "use async_tungstenite::tungstenite::{error::ProtocolError, handshake::derive_accept_key};\n\nuse hyper::{\n HeaderMap, R"
},
{
"path": "crates/lune-std-net/src/shared/futures.rs",
"chars": 577,
"preview": "use futures_lite::prelude::*;\n\npub use http_body_util::Either;\n\n/**\n Combines the left and right futures into a singl"
},
{
"path": "crates/lune-std-net/src/shared/headers.rs",
"chars": 2550,
"preview": "use std::collections::HashMap;\n\nuse hyper::{\n HeaderMap,\n header::{CONTENT_ENCODING, CONTENT_LENGTH},\n};\n\nuse lune"
},
{
"path": "crates/lune-std-net/src/shared/hyper.rs",
"chars": 5058,
"preview": "use std::{\n future::Future,\n io,\n pin::Pin,\n slice,\n task::{Context, Poll},\n time::{Duration, Instant}"
},
{
"path": "crates/lune-std-net/src/shared/lua.rs",
"chars": 1283,
"preview": "use hyper::{\n HeaderMap, Method,\n header::{HeaderName, HeaderValue},\n};\n\nuse mlua::prelude::*;\n\npub fn lua_value_t"
},
{
"path": "crates/lune-std-net/src/shared/mod.rs",
"chars": 129,
"preview": "pub mod futures;\npub mod headers;\npub mod hyper;\npub mod lua;\npub mod request;\npub mod response;\npub mod tcp;\npub mod we"
},
{
"path": "crates/lune-std-net/src/shared/request.rs",
"chars": 8336,
"preview": "use std::{collections::HashMap, net::SocketAddr};\n\nuse url::Url;\n\nuse hyper::{HeaderMap, Method, Request as HyperRequest"
},
{
"path": "crates/lune-std-net/src/shared/response.rs",
"chars": 4554,
"preview": "use hyper::{\n HeaderMap, Response as HyperResponse, StatusCode,\n body::Incoming,\n header::{CONTENT_TYPE, Header"
},
{
"path": "crates/lune-std-net/src/shared/tcp.rs",
"chars": 3120,
"preview": "use std::{io::Error, net::SocketAddr, sync::Arc};\n\nuse async_lock::Mutex as AsyncMutex;\nuse bstr::BString;\nuse futures::"
},
{
"path": "crates/lune-std-net/src/shared/websocket.rs",
"chars": 4967,
"preview": "use std::{\n error::Error,\n sync::{\n Arc,\n atomic::{AtomicBool, AtomicU16, Ordering},\n },\n};\n\nuse "
},
{
"path": "crates/lune-std-net/src/url/decode.rs",
"chars": 421,
"preview": "use mlua::prelude::*;\n\npub fn decode(lua_string: LuaString, as_binary: bool) -> LuaResult<Vec<u8>> {\n if as_binary {\n"
},
{
"path": "crates/lune-std-net/src/url/encode.rs",
"chars": 363,
"preview": "use mlua::prelude::*;\n\npub fn encode(lua_string: LuaString, as_binary: bool) -> LuaResult<Vec<u8>> {\n if as_binary {\n"
},
{
"path": "crates/lune-std-net/src/url/mod.rs",
"chars": 85,
"preview": "mod decode;\nmod encode;\n\npub use self::decode::decode;\npub use self::encode::encode;\n"
},
{
"path": "crates/lune-std-net/types.d.luau",
"chars": 11444,
"preview": "export type HttpMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"HEAD\" | \"OPTIONS\" | \"PATCH\"\n\ntype HttpQueryOrHeaderMap = {"
},
{
"path": "crates/lune-std-process/Cargo.toml",
"chars": 668,
"preview": "[package]\nname = \"lune-std-process\"\nversion = \"0.3.4\"\nedition = \"2024\"\nlicense = \"MPL-2.0\"\nrepository = \"https://github."
},
{
"path": "crates/lune-std-process/src/create/child.rs",
"chars": 2697,
"preview": "use std::process::ExitStatus;\n\nuse async_channel::{Receiver, Sender, unbounded};\nuse async_process::Child as AsyncChild;"
},
{
"path": "crates/lune-std-process/src/create/child_reader.rs",
"chars": 3405,
"preview": "use std::sync::Arc;\n\nuse async_lock::Mutex as AsyncMutex;\nuse async_process::{ChildStderr as AsyncChildStderr, ChildStdo"
},
{
"path": "crates/lune-std-process/src/create/child_writer.rs",
"chars": 2098,
"preview": "use std::sync::Arc;\n\nuse async_lock::Mutex as AsyncMutex;\nuse async_process::ChildStdin as AsyncChildStdin;\nuse futures_"
},
{
"path": "crates/lune-std-process/src/create/mod.rs",
"chars": 158,
"preview": "mod child;\nmod child_reader;\nmod child_writer;\n\npub use self::child::Child;\npub use self::child_reader::ChildReader;\npub"
},
{
"path": "crates/lune-std-process/src/exec/mod.rs",
"chars": 1482,
"preview": "use async_process::Child;\nuse futures_lite::prelude::*;\n\nuse mlua::prelude::*;\n\nuse lune_utils::TableBuilder;\n\nuse super"
},
{
"path": "crates/lune-std-process/src/exec/tee_writer.rs",
"chars": 1422,
"preview": "use std::{\n io::Write,\n pin::Pin,\n task::{Context, Poll},\n};\n\nuse futures_lite::{io, prelude::*};\nuse pin_proje"
},
{
"path": "crates/lune-std-process/src/exec/wait_for_child.rs",
"chars": 1989,
"preview": "use std::{io::stdout, process::ExitStatus};\n\nuse mlua::prelude::*;\n\nuse async_process::Child;\nuse blocking::Unblock;\nuse"
},
{
"path": "crates/lune-std-process/src/lib.rs",
"chars": 3481,
"preview": "#![allow(clippy::cargo_common_metadata)]\n\nuse std::{\n env::consts::{ARCH, OS},\n path::MAIN_SEPARATOR,\n process:"
},
{
"path": "crates/lune-std-process/src/options/kind.rs",
"chars": 2430,
"preview": "use std::{fmt, process::Stdio, str::FromStr};\n\nuse mlua::prelude::*;\n\n#[derive(Debug, Clone, Copy, Default, PartialEq, E"
},
{
"path": "crates/lune-std-process/src/options/mod.rs",
"chars": 5208,
"preview": "use std::{\n collections::HashMap,\n env::{self},\n ffi::OsString,\n path::PathBuf,\n};\n\nuse lune_utils::process:"
},
{
"path": "crates/lune-std-process/src/options/stdio.rs",
"chars": 1746,
"preview": "use bstr::BString;\nuse mlua::prelude::*;\n\nuse super::kind::ProcessSpawnOptionsStdioKind;\n\n#[derive(Debug, Clone, Default"
},
{
"path": "crates/lune-std-process/types.d.luau",
"chars": 10151,
"preview": "export type OS = \"linux\" | \"macos\" | \"windows\"\nexport type Arch = \"x86_64\" | \"aarch64\"\nexport type Endianness = \"big\" | "
},
{
"path": "crates/lune-std-regex/Cargo.toml",
"chars": 397,
"preview": "[package]\nname = \"lune-std-regex\"\nversion = \"0.3.4\"\nedition = \"2024\"\nlicense = \"MPL-2.0\"\nrepository = \"https://github.co"
},
{
"path": "crates/lune-std-regex/src/captures.rs",
"chars": 2543,
"preview": "use std::sync::Arc;\n\nuse mlua::prelude::*;\nuse regex::{Captures, Regex};\nuse self_cell::self_cell;\n\nuse super::matches::"
},
{
"path": "crates/lune-std-regex/src/lib.rs",
"chars": 758,
"preview": "#![allow(clippy::cargo_common_metadata)]\n\nuse mlua::prelude::*;\n\nuse lune_utils::TableBuilder;\n\nmod captures;\nmod matche"
},
{
"path": "crates/lune-std-regex/src/matches.rs",
"chars": 1566,
"preview": "use std::{ops::Range, sync::Arc};\n\nuse mlua::prelude::*;\nuse regex::Match;\n\n/**\n A wrapper over the `regex::Match` st"
},
{
"path": "crates/lune-std-regex/src/regex.rs",
"chars": 2224,
"preview": "use std::sync::Arc;\n\nuse mlua::prelude::*;\nuse regex::Regex;\n\nuse super::{captures::LuaCaptures, matches::LuaMatch};\n\n/*"
},
{
"path": "crates/lune-std-regex/types.d.luau",
"chars": 5048,
"preview": "--[=[\n\t@class RegexMatch\n\n\tA match from a regular expression.\n\n\tContains the following values:\n\n\t- `start` -- The start "
},
{
"path": "crates/lune-std-roblox/Cargo.toml",
"chars": 588,
"preview": "[package]\nname = \"lune-std-roblox\"\nversion = \"0.3.4\"\nedition = \"2024\"\nlicense = \"MPL-2.0\"\nrepository = \"https://github.c"
},
{
"path": "crates/lune-std-roblox/src/lib.rs",
"chars": 6114,
"preview": "#![allow(clippy::cargo_common_metadata)]\n\nuse std::sync::OnceLock;\n\nuse mlua::prelude::*;\nuse mlua_luau_scheduler::LuaSp"
},
{
"path": "crates/lune-std-roblox/types.d.luau",
"chars": 16060,
"preview": "export type DatabaseScriptability = \"None\" | \"Custom\" | \"Read\" | \"ReadWrite\" | \"Write\"\n\nexport type DatabasePropertyTag "
},
{
"path": "crates/lune-std-serde/Cargo.toml",
"chars": 1197,
"preview": "[package]\nname = \"lune-std-serde\"\nversion = \"0.3.4\"\nedition = \"2024\"\nlicense = \"MPL-2.0\"\nrepository = \"https://github.co"
},
{
"path": "crates/lune-std-serde/src/compress_decompress.rs",
"chars": 8422,
"preview": "use std::io::{Cursor, Read as _, Write as _, copy as copy_std};\n\nuse mlua::prelude::*;\n\nuse blocking::unblock;\nuse futur"
},
{
"path": "crates/lune-std-serde/src/encode_decode.rs",
"chars": 5519,
"preview": "use mlua::prelude::*;\n\nuse serde_json::Value as JsonValue;\nuse serde_yaml2::wrapper::YamlNodeWrapper as YamlValue;\nuse t"
},
{
"path": "crates/lune-std-serde/src/hash.rs",
"chars": 8818,
"preview": "use std::fmt::Write;\n\nuse bstr::BString;\nuse md5::Md5;\nuse mlua::prelude::*;\n\nuse blake3::Hasher as Blake3;\nuse sha1::Sh"
},
{
"path": "crates/lune-std-serde/src/lib.rs",
"chars": 2234,
"preview": "#![allow(clippy::cargo_common_metadata)]\n\nuse bstr::BString;\nuse mlua::prelude::*;\n\nuse lune_utils::TableBuilder;\n\nmod c"
},
{
"path": "crates/lune-std-serde/types.d.luau",
"chars": 5648,
"preview": "--[=[\n\t@within Serde\n\t@interface EncodeDecodeFormat\n\n\tA serialization/deserialization format supported by the Serde libr"
},
{
"path": "crates/lune-std-stdio/Cargo.toml",
"chars": 548,
"preview": "[package]\nname = \"lune-std-stdio\"\nversion = \"0.3.4\"\nedition = \"2024\"\nlicense = \"MPL-2.0\"\nrepository = \"https://github.co"
},
{
"path": "crates/lune-std-stdio/src/lib.rs",
"chars": 3126,
"preview": "#![allow(clippy::cargo_common_metadata)]\n\nuse std::{\n io::{Stdin, stderr, stdin, stdout},\n sync::{Arc, LazyLock},\n"
},
{
"path": "crates/lune-std-stdio/src/prompt.rs",
"chars": 7618,
"preview": "use std::{fmt, str::FromStr};\n\nuse dialoguer::{Confirm, Input, MultiSelect, Select, theme::ColorfulTheme};\nuse mlua::pre"
},
{
"path": "crates/lune-std-stdio/src/style_and_color.rs",
"chars": 5386,
"preview": "use std::str::FromStr;\n\nuse mlua::prelude::*;\n\nconst ESCAPE_SEQ_RESET: &str = \"\\x1b[0m\";\n\n/**\n A color kind supported"
},
{
"path": "crates/lune-std-stdio/types.d.luau",
"chars": 4017,
"preview": "export type Color = \"reset\" | \"black\" | \"red\" | \"green\" | \"yellow\" | \"blue\" | \"purple\" | \"cyan\" | \"white\"\nexport type St"
},
{
"path": "crates/lune-std-task/Cargo.toml",
"chars": 477,
"preview": "[package]\nname = \"lune-std-task\"\nversion = \"0.3.4\"\nedition = \"2024\"\nlicense = \"MPL-2.0\"\nrepository = \"https://github.com"
},
{
"path": "crates/lune-std-task/src/lib.rs",
"chars": 2674,
"preview": "#![allow(clippy::cargo_common_metadata)]\n\nuse std::time::{Duration, Instant};\n\nuse async_io::Timer;\nuse futures_lite::fu"
},
{
"path": "crates/lune-std-task/types.d.luau",
"chars": 2190,
"preview": "--[=[\n\t@class Task\n\n\tBuilt-in task scheduler & thread spawning\n\n\t### Example usage\n\n\t```lua\n\tlocal task = require(\"@lune"
},
{
"path": "crates/lune-utils/Cargo.toml",
"chars": 457,
"preview": "[package]\nname = \"lune-utils\"\nversion = \"0.3.4\"\nedition = \"2024\"\nlicense = \"MPL-2.0\"\nrepository = \"https://github.com/lu"
},
{
"path": "crates/lune-utils/src/fmt/error/components.rs",
"chars": 6282,
"preview": "use std::{\n fmt,\n str::FromStr,\n sync::{Arc, LazyLock},\n};\n\nuse console::style;\nuse mlua::prelude::*;\n\nuse supe"
},
{
"path": "crates/lune-utils/src/fmt/error/mod.rs",
"chars": 177,
"preview": "mod components;\nmod stack_trace;\n\n#[cfg(test)]\nmod tests;\n\npub use self::components::ErrorComponents;\npub use self::stac"
}
]
// ... and 257 more files (download for full content)
About this extraction
This page contains the full source code of the filiptibell/lune GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 457 files (1.1 MB), approximately 295.9k tokens, and a symbol index with 1478 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.