mirror of
https://github.com/lune-org/lune.git
synced 2024-12-12 13:00:37 +00:00
Split lune into proper crates (#188)
This commit is contained in:
parent
3f53fc983c
commit
de71558c5d
185 changed files with 4005 additions and 1897 deletions
4
.github/workflows/ci.yaml
vendored
4
.github/workflows/ci.yaml
vendored
|
@ -24,7 +24,7 @@ jobs:
|
||||||
components: rustfmt
|
components: rustfmt
|
||||||
|
|
||||||
- name: Install Just
|
- name: Install Just
|
||||||
uses: extractions/setup-just@v1
|
uses: extractions/setup-just@v2
|
||||||
|
|
||||||
- name: Install Tooling
|
- name: Install Tooling
|
||||||
uses: ok-nick/setup-aftman@v0.4.2
|
uses: ok-nick/setup-aftman@v0.4.2
|
||||||
|
@ -41,7 +41,7 @@ jobs:
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Just
|
- name: Install Just
|
||||||
uses: extractions/setup-just@v1
|
uses: extractions/setup-just@v2
|
||||||
|
|
||||||
- name: Install Tooling
|
- name: Install Tooling
|
||||||
uses: ok-nick/setup-aftman@v0.4.2
|
uses: ok-nick/setup-aftman@v0.4.2
|
||||||
|
|
24
.github/workflows/publish.yaml
vendored
24
.github/workflows/publish.yaml
vendored
|
@ -1,24 +0,0 @@
|
||||||
name: Publish
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- "main"
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
publish:
|
|
||||||
name: Publish
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install Rust
|
|
||||||
uses: dtolnay/rust-toolchain@stable
|
|
||||||
|
|
||||||
- name: Publish to crates.io
|
|
||||||
uses: katyo/publish-crates@v2
|
|
||||||
with:
|
|
||||||
registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
|
||||||
ignore-unpublished-changes: true
|
|
56
.github/workflows/release.yaml
vendored
56
.github/workflows/release.yaml
vendored
|
@ -21,14 +21,32 @@ jobs:
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Get version from manifest
|
- name: Get version from manifest
|
||||||
uses: SebRollen/toml-action@9062fbef52816d61278d24ce53c8070440e1e8dd
|
uses: SebRollen/toml-action@v1.2.0
|
||||||
id: get_version
|
id: get_version
|
||||||
with:
|
with:
|
||||||
file: Cargo.toml
|
file: Cargo.toml
|
||||||
field: package.version
|
field: package.version
|
||||||
|
|
||||||
build:
|
dry-run:
|
||||||
|
name: Dry-run
|
||||||
needs: ["init"]
|
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:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
|
@ -70,7 +88,7 @@ jobs:
|
||||||
targets: ${{ matrix.cargo-target }}
|
targets: ${{ matrix.cargo-target }}
|
||||||
|
|
||||||
- name: Install Just
|
- name: Install Just
|
||||||
uses: extractions/setup-just@v1
|
uses: extractions/setup-just@v2
|
||||||
|
|
||||||
- name: Install build tooling (aarch64-unknown-linux-gnu)
|
- name: Install build tooling (aarch64-unknown-linux-gnu)
|
||||||
if: matrix.cargo-target == 'aarch64-unknown-linux-gnu'
|
if: matrix.cargo-target == 'aarch64-unknown-linux-gnu'
|
||||||
|
@ -86,24 +104,24 @@ jobs:
|
||||||
run: just zip-release ${{ matrix.cargo-target }}
|
run: just zip-release ${{ matrix.cargo-target }}
|
||||||
|
|
||||||
- name: Upload release artifact
|
- name: Upload release artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.artifact-name }}
|
name: ${{ matrix.artifact-name }}
|
||||||
path: release.zip
|
path: release.zip
|
||||||
|
|
||||||
release:
|
release-github:
|
||||||
name: Release
|
name: Release (GitHub)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: ["init", "build"]
|
needs: ["init", "dry-run", "build"]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Just
|
- name: Install Just
|
||||||
uses: extractions/setup-just@v1
|
uses: extractions/setup-just@v2
|
||||||
|
|
||||||
- name: Download releases
|
- name: Download releases
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: ./releases
|
path: ./releases
|
||||||
|
|
||||||
|
@ -111,7 +129,7 @@ jobs:
|
||||||
run: just unpack-releases "./releases"
|
run: just unpack-releases "./releases"
|
||||||
|
|
||||||
- name: Create release
|
- name: Create release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v2
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
|
@ -120,3 +138,21 @@ jobs:
|
||||||
fail_on_unmatched_files: true
|
fail_on_unmatched_files: true
|
||||||
files: ./releases/*.zip
|
files: ./releases/*.zip
|
||||||
draft: true
|
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 }}
|
||||||
|
|
270
Cargo.lock
generated
270
Cargo.lock
generated
|
@ -163,9 +163,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-compression"
|
name = "async-compression"
|
||||||
version = "0.4.8"
|
version = "0.4.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "07dbbf24db18d609b1462965249abdf49129ccad073ec257da372adc83259c60"
|
checksum = "9c90a406b4495d129f00461241616194cb8a032c8d1c53c657f0961d5f8e0498"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"brotli",
|
"brotli",
|
||||||
"flate2",
|
"flate2",
|
||||||
|
@ -205,17 +205,6 @@ version = "4.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799"
|
checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "async-trait"
|
|
||||||
version = "0.1.80"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.60",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atomic-waker"
|
name = "atomic-waker"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
|
@ -324,9 +313,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "brotli"
|
name = "brotli"
|
||||||
version = "4.0.0"
|
version = "6.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "125740193d7fee5cc63ab9e16c2fdc4e07c74ba755cc53b327d6ea029e9fc569"
|
checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloc-no-stdlib",
|
"alloc-no-stdlib",
|
||||||
"alloc-stdlib",
|
"alloc-stdlib",
|
||||||
|
@ -335,9 +324,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "brotli-decompressor"
|
name = "brotli-decompressor"
|
||||||
version = "3.0.0"
|
version = "4.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "65622a320492e09b5e0ac436b14c54ff68199bac392d0e89a6832c4518eea525"
|
checksum = "e6221fe77a248b9117d431ad93761222e1cf8ff282d9d1d5d9f53d6299a1cf76"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloc-no-stdlib",
|
"alloc-no-stdlib",
|
||||||
"alloc-stdlib",
|
"alloc-stdlib",
|
||||||
|
@ -759,12 +748,6 @@ version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b"
|
checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "either"
|
|
||||||
version = "1.11.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encode_unicode"
|
name = "encode_unicode"
|
||||||
version = "0.3.6"
|
version = "0.3.6"
|
||||||
|
@ -1367,15 +1350,6 @@ version = "2.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
|
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itertools"
|
|
||||||
version = "0.12.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
|
||||||
dependencies = [
|
|
||||||
"either",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.11"
|
version = "1.0.11"
|
||||||
|
@ -1484,57 +1458,203 @@ name = "lune"
|
||||||
version = "0.8.3"
|
version = "0.8.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-compression",
|
|
||||||
"async-trait",
|
|
||||||
"blocking",
|
|
||||||
"bstr",
|
|
||||||
"chrono",
|
|
||||||
"chrono_lc",
|
|
||||||
"clap",
|
"clap",
|
||||||
"console",
|
"console",
|
||||||
"dialoguer",
|
"dialoguer",
|
||||||
"directories",
|
"directories",
|
||||||
"dunce",
|
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
"include_dir",
|
||||||
|
"lune-roblox",
|
||||||
|
"lune-std",
|
||||||
|
"lune-utils",
|
||||||
|
"mlua",
|
||||||
|
"mlua-luau-scheduler",
|
||||||
|
"once_cell",
|
||||||
|
"reqwest",
|
||||||
|
"rustyline",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
|
"zip_next",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lune-roblox"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
"glam",
|
"glam",
|
||||||
|
"lune-utils",
|
||||||
|
"mlua",
|
||||||
|
"once_cell",
|
||||||
|
"rand",
|
||||||
|
"rbx_binary",
|
||||||
|
"rbx_dom_weak",
|
||||||
|
"rbx_reflection",
|
||||||
|
"rbx_reflection_database",
|
||||||
|
"rbx_xml",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lune-std"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"lune-std-datetime",
|
||||||
|
"lune-std-fs",
|
||||||
|
"lune-std-luau",
|
||||||
|
"lune-std-net",
|
||||||
|
"lune-std-process",
|
||||||
|
"lune-std-regex",
|
||||||
|
"lune-std-roblox",
|
||||||
|
"lune-std-serde",
|
||||||
|
"lune-std-stdio",
|
||||||
|
"lune-std-task",
|
||||||
|
"lune-utils",
|
||||||
|
"mlua",
|
||||||
|
"mlua-luau-scheduler",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lune-std-datetime"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"chrono_lc",
|
||||||
|
"lune-utils",
|
||||||
|
"mlua",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lune-std-fs"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bstr",
|
||||||
|
"lune-std-datetime",
|
||||||
|
"lune-utils",
|
||||||
|
"mlua",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lune-std-luau"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"lune-utils",
|
||||||
|
"mlua",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lune-std-net"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bstr",
|
||||||
|
"futures-util",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper 1.3.1",
|
"hyper 1.3.1",
|
||||||
"hyper-tungstenite",
|
"hyper-tungstenite",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
"include_dir",
|
"lune-std-serde",
|
||||||
"itertools",
|
"lune-utils",
|
||||||
"lz4_flex",
|
"mlua",
|
||||||
|
"mlua-luau-scheduler",
|
||||||
|
"reqwest",
|
||||||
|
"tokio",
|
||||||
|
"tokio-tungstenite",
|
||||||
|
"urlencoding",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lune-std-process"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"directories",
|
||||||
|
"lune-utils",
|
||||||
|
"mlua",
|
||||||
|
"mlua-luau-scheduler",
|
||||||
|
"os_str_bytes",
|
||||||
|
"pin-project",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lune-std-regex"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"lune-utils",
|
||||||
|
"mlua",
|
||||||
|
"regex",
|
||||||
|
"self_cell",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lune-std-roblox"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"lune-roblox",
|
||||||
|
"lune-utils",
|
||||||
"mlua",
|
"mlua",
|
||||||
"mlua-luau-scheduler",
|
"mlua-luau-scheduler",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"os_str_bytes",
|
|
||||||
"path-clean",
|
|
||||||
"pathdiff",
|
|
||||||
"pin-project",
|
|
||||||
"rand",
|
|
||||||
"rbx_binary",
|
|
||||||
"rbx_cookie",
|
"rbx_cookie",
|
||||||
"rbx_dom_weak",
|
]
|
||||||
"rbx_reflection",
|
|
||||||
"rbx_reflection_database",
|
[[package]]
|
||||||
"rbx_xml",
|
name = "lune-std-serde"
|
||||||
"regex",
|
version = "0.1.0"
|
||||||
"reqwest",
|
dependencies = [
|
||||||
"rustyline",
|
"async-compression",
|
||||||
"self_cell",
|
"bstr",
|
||||||
|
"lune-utils",
|
||||||
|
"lz4",
|
||||||
|
"mlua",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"thiserror",
|
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-tungstenite",
|
|
||||||
"toml",
|
"toml",
|
||||||
"tracing",
|
]
|
||||||
"tracing-subscriber",
|
|
||||||
"urlencoding",
|
[[package]]
|
||||||
"zip_next",
|
name = "lune-std-stdio"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"dialoguer",
|
||||||
|
"lune-utils",
|
||||||
|
"mlua",
|
||||||
|
"mlua-luau-scheduler",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lune-std-task"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"lune-utils",
|
||||||
|
"mlua",
|
||||||
|
"mlua-luau-scheduler",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lune-utils"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"console",
|
||||||
|
"dunce",
|
||||||
|
"mlua",
|
||||||
|
"once_cell",
|
||||||
|
"path-clean",
|
||||||
|
"pathdiff",
|
||||||
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1557,15 +1677,6 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lz4_flex"
|
|
||||||
version = "0.11.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5"
|
|
||||||
dependencies = [
|
|
||||||
"twox-hash",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lzma-rs"
|
name = "lzma-rs"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
@ -2624,12 +2735,6 @@ dependencies = [
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "static_assertions"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stdweb"
|
name = "stdweb"
|
||||||
version = "0.4.20"
|
version = "0.4.20"
|
||||||
|
@ -2882,7 +2987,6 @@ dependencies = [
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
"tracing",
|
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -3100,16 +3204,6 @@ dependencies = [
|
||||||
"utf-8",
|
"utf-8",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "twox-hash"
|
|
||||||
version = "1.6.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"static_assertions",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typed-arena"
|
name = "typed-arena"
|
||||||
version = "2.0.2"
|
version = "2.0.2"
|
||||||
|
|
172
Cargo.toml
172
Cargo.toml
|
@ -1,41 +1,21 @@
|
||||||
[package]
|
[workspace]
|
||||||
name = "lune"
|
resolver = "2"
|
||||||
version = "0.8.3"
|
default-members = ["crates/lune"]
|
||||||
edition = "2021"
|
members = [
|
||||||
license = "MPL-2.0"
|
"crates/lune",
|
||||||
repository = "https://github.com/lune-org/lune"
|
"crates/lune-roblox",
|
||||||
description = "A standalone Luau runtime"
|
"crates/lune-std",
|
||||||
readme = "README.md"
|
"crates/lune-std-datetime",
|
||||||
keywords = ["cli", "lua", "luau", "runtime"]
|
"crates/lune-std-fs",
|
||||||
categories = ["command-line-interface"]
|
"crates/lune-std-luau",
|
||||||
|
"crates/lune-std-net",
|
||||||
[[bin]]
|
"crates/lune-std-process",
|
||||||
name = "lune"
|
"crates/lune-std-regex",
|
||||||
path = "src/main.rs"
|
"crates/lune-std-roblox",
|
||||||
|
"crates/lune-std-serde",
|
||||||
[lib]
|
"crates/lune-std-stdio",
|
||||||
name = "lune"
|
"crates/lune-std-task",
|
||||||
path = "src/lib.rs"
|
"crates/lune-utils",
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["cli", "roblox"]
|
|
||||||
cli = [
|
|
||||||
"dep:anyhow",
|
|
||||||
"dep:env_logger",
|
|
||||||
"dep:clap",
|
|
||||||
"dep:include_dir",
|
|
||||||
"dep:rustyline",
|
|
||||||
"dep:zip_next",
|
|
||||||
]
|
|
||||||
roblox = [
|
|
||||||
"dep:glam",
|
|
||||||
"dep:rand",
|
|
||||||
"dep:rbx_cookie",
|
|
||||||
"dep:rbx_binary",
|
|
||||||
"dep:rbx_dom_weak",
|
|
||||||
"dep:rbx_reflection",
|
|
||||||
"dep:rbx_reflection_database",
|
|
||||||
"dep:rbx_xml",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# Profile for building the release binary, with the following options set:
|
# Profile for building the release binary, with the following options set:
|
||||||
|
@ -53,99 +33,31 @@ opt-level = "z"
|
||||||
strip = true
|
strip = true
|
||||||
lto = true
|
lto = true
|
||||||
|
|
||||||
# All of the dependencies for Lune.
|
# Lints for all crates in the workspace
|
||||||
#
|
#
|
||||||
# Dependencies are categorized as following:
|
# 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:
|
||||||
# 1. General dependencies with no specific features set
|
# - Casts between number types
|
||||||
# 2. Large / core dependencies that have many different crates and / or features set
|
# - Module naming conventions
|
||||||
# 3. Dependencies for specific features of Lune, eg. the CLI or massive Roblox builtin library
|
# - Imports and multiple dependency versions
|
||||||
#
|
[workspace.lints.clippy]
|
||||||
[dependencies]
|
all = { level = "deny", priority = -3 }
|
||||||
console = "0.15"
|
cargo = { level = "warn", priority = -2 }
|
||||||
directories = "5.0"
|
pedantic = { level = "warn", priority = -1 }
|
||||||
futures-util = "0.3"
|
|
||||||
once_cell = "1.17"
|
|
||||||
thiserror = "1.0"
|
|
||||||
async-trait = "0.1"
|
|
||||||
dialoguer = "0.11"
|
|
||||||
dunce = "1.0"
|
|
||||||
lz4_flex = "0.11"
|
|
||||||
path-clean = "1.0"
|
|
||||||
pathdiff = "0.2"
|
|
||||||
pin-project = "1.0"
|
|
||||||
urlencoding = "2.1"
|
|
||||||
bstr = "1.9"
|
|
||||||
regex = "1.10"
|
|
||||||
self_cell = "1.0"
|
|
||||||
|
|
||||||
### RUNTIME
|
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 }
|
||||||
|
|
||||||
blocking = "1.5"
|
similar_names = { level = "allow", priority = 1 }
|
||||||
tracing = "0.1"
|
unnecessary_wraps = { level = "allow", priority = 1 }
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
unnested_or_patterns = { level = "allow", priority = 1 }
|
||||||
tokio = { version = "1.24", features = ["full", "tracing"] }
|
unreadable_literal = { level = "allow", priority = 1 }
|
||||||
os_str_bytes = { version = "7.0", features = ["conversions"] }
|
|
||||||
|
|
||||||
mlua-luau-scheduler = { version = "0.0.2" }
|
multiple_crate_versions = { level = "allow", priority = 1 }
|
||||||
mlua = { version = "0.9.7", features = [
|
module_inception = { level = "allow", priority = 1 }
|
||||||
"luau",
|
module_name_repetitions = { level = "allow", priority = 1 }
|
||||||
"luau-jit",
|
needless_pass_by_value = { level = "allow", priority = 1 }
|
||||||
"async",
|
wildcard_imports = { level = "allow", priority = 1 }
|
||||||
"serialize",
|
|
||||||
] }
|
|
||||||
|
|
||||||
### SERDE
|
|
||||||
|
|
||||||
async-compression = { version = "0.4", features = [
|
|
||||||
"tokio",
|
|
||||||
"brotli",
|
|
||||||
"deflate",
|
|
||||||
"gzip",
|
|
||||||
"zlib",
|
|
||||||
] }
|
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
|
||||||
serde_json = { version = "1.0", features = ["preserve_order"] }
|
|
||||||
serde_yaml = "0.9"
|
|
||||||
toml = { version = "0.8", features = ["preserve_order"] }
|
|
||||||
|
|
||||||
### NET
|
|
||||||
|
|
||||||
hyper = { version = "1.1", features = ["full"] }
|
|
||||||
hyper-util = { version = "0.1", features = ["full"] }
|
|
||||||
http = "1.0"
|
|
||||||
http-body-util = { version = "0.1" }
|
|
||||||
hyper-tungstenite = { version = "0.13" }
|
|
||||||
|
|
||||||
reqwest = { version = "0.11", default-features = false, features = [
|
|
||||||
"rustls-tls",
|
|
||||||
] }
|
|
||||||
|
|
||||||
tokio-tungstenite = { version = "0.21", features = ["rustls-tls-webpki-roots"] }
|
|
||||||
|
|
||||||
### DATETIME
|
|
||||||
chrono = "=0.4.34" # NOTE: 0.4.35 does not compile with chrono_lc
|
|
||||||
chrono_lc = "0.1"
|
|
||||||
|
|
||||||
### CLI
|
|
||||||
|
|
||||||
anyhow = { optional = true, version = "1.0" }
|
|
||||||
env_logger = { optional = true, version = "0.11" }
|
|
||||||
itertools = "0.12"
|
|
||||||
clap = { optional = true, version = "4.1", features = ["derive"] }
|
|
||||||
include_dir = { optional = true, version = "0.7", features = ["glob"] }
|
|
||||||
rustyline = { optional = true, version = "14.0" }
|
|
||||||
zip_next = { optional = true, version = "1.1" }
|
|
||||||
|
|
||||||
### ROBLOX
|
|
||||||
|
|
||||||
glam = { optional = true, version = "0.27" }
|
|
||||||
rand = { optional = true, version = "0.8" }
|
|
||||||
|
|
||||||
rbx_cookie = { optional = true, version = "0.1.4", default-features = false }
|
|
||||||
|
|
||||||
rbx_binary = { optional = true, version = "0.7.3" }
|
|
||||||
rbx_dom_weak = { optional = true, version = "2.6.0" }
|
|
||||||
rbx_reflection = { optional = true, version = "4.4.0" }
|
|
||||||
rbx_reflection_database = { optional = true, version = "0.2.9" }
|
|
||||||
rbx_xml = { optional = true, version = "0.13.2" }
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
[tools]
|
[tools]
|
||||||
luau-lsp = "JohnnyMorganz/luau-lsp@1.27.0"
|
luau-lsp = "JohnnyMorganz/luau-lsp@1.29.0"
|
||||||
selene = "Kampfkarren/selene@0.26.1"
|
selene = "Kampfkarren/selene@0.27.1"
|
||||||
stylua = "JohnnyMorganz/StyLua@0.19.1"
|
stylua = "JohnnyMorganz/StyLua@0.20.0"
|
||||||
|
|
27
crates/lune-roblox/Cargo.toml
Normal file
27
crates/lune-roblox/Cargo.toml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
[package]
|
||||||
|
name = "lune-roblox"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
license = "MPL-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
mlua = { version = "0.9.7", features = ["luau"] }
|
||||||
|
|
||||||
|
glam = "0.27"
|
||||||
|
rand = "0.8"
|
||||||
|
thiserror = "1.0"
|
||||||
|
once_cell = "1.17"
|
||||||
|
|
||||||
|
rbx_binary = "0.7.3"
|
||||||
|
rbx_dom_weak = "2.6.0"
|
||||||
|
rbx_reflection = "4.4.0"
|
||||||
|
rbx_reflection_database = "0.2.9"
|
||||||
|
rbx_xml = "0.13.2"
|
||||||
|
|
||||||
|
lune-utils = { version = "0.1.0", path = "../lune-utils" }
|
|
@ -4,6 +4,15 @@ use rbx_dom_weak::types::{Variant as DomValue, VariantType as DomType};
|
||||||
|
|
||||||
use super::extension::DomValueExt;
|
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 and underscore.
|
||||||
|
- If the name is longer than 100 characters.
|
||||||
|
*/
|
||||||
pub fn ensure_valid_attribute_name(name: impl AsRef<str>) -> LuaResult<()> {
|
pub fn ensure_valid_attribute_name(name: impl AsRef<str>) -> LuaResult<()> {
|
||||||
let name = name.as_ref();
|
let name = name.as_ref();
|
||||||
if name.to_ascii_uppercase().starts_with("RBX") {
|
if name.to_ascii_uppercase().starts_with("RBX") {
|
||||||
|
@ -23,6 +32,13 @@ pub fn ensure_valid_attribute_name(name: impl AsRef<str>) -> LuaResult<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
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<()> {
|
pub fn ensure_valid_attribute_value(value: &DomValue) -> LuaResult<()> {
|
||||||
let is_valid = matches!(
|
let is_valid = matches!(
|
||||||
value.ty(),
|
value.ty(),
|
|
@ -2,7 +2,7 @@ use mlua::prelude::*;
|
||||||
|
|
||||||
use rbx_dom_weak::types::{Variant as DomValue, VariantType as DomType};
|
use rbx_dom_weak::types::{Variant as DomValue, VariantType as DomType};
|
||||||
|
|
||||||
use crate::roblox::{datatypes::extension::DomValueExt, instance::Instance};
|
use crate::{datatypes::extension::DomValueExt, instance::Instance};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -65,8 +65,10 @@ impl<'lua> DomValueToLua<'lua> for LuaValue<'lua> {
|
||||||
|
|
||||||
// NOTE: Some values are either optional or default and we should handle
|
// NOTE: Some values are either optional or default and we should handle
|
||||||
// that properly here since the userdata conversion above will always fail
|
// that properly here since the userdata conversion above will always fail
|
||||||
DomValue::OptionalCFrame(None) => Ok(LuaValue::Nil),
|
DomValue::OptionalCFrame(None)
|
||||||
DomValue::PhysicalProperties(dom::PhysicalProperties::Default) => Ok(LuaValue::Nil),
|
| DomValue::PhysicalProperties(dom::PhysicalProperties::Default) => {
|
||||||
|
Ok(LuaValue::Nil)
|
||||||
|
}
|
||||||
|
|
||||||
_ => Err(e),
|
_ => Err(e),
|
||||||
},
|
},
|
|
@ -6,6 +6,7 @@ pub(crate) trait DomValueExt {
|
||||||
|
|
||||||
impl DomValueExt for DomType {
|
impl DomValueExt for DomType {
|
||||||
fn variant_name(&self) -> Option<&'static str> {
|
fn variant_name(&self) -> Option<&'static str> {
|
||||||
|
#[allow(clippy::enum_glob_use)]
|
||||||
use DomType::*;
|
use DomType::*;
|
||||||
Some(match self {
|
Some(match self {
|
||||||
Attributes => "Attributes",
|
Attributes => "Attributes",
|
|
@ -10,4 +10,4 @@ mod util;
|
||||||
|
|
||||||
use result::*;
|
use result::*;
|
||||||
|
|
||||||
pub use crate::roblox::shared::userdata::*;
|
pub use crate::shared::userdata::*;
|
|
@ -3,7 +3,9 @@ use core::fmt;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::Axes as DomAxes;
|
use rbx_dom_weak::types::Axes as DomAxes;
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::{super::*, EnumItem};
|
use super::{super::*, EnumItem};
|
||||||
|
|
||||||
|
@ -52,8 +54,7 @@ impl LuaExportsTable<'_> for Axes {
|
||||||
check(&e);
|
check(&e);
|
||||||
} else {
|
} else {
|
||||||
return Err(LuaError::RuntimeError(format!(
|
return Err(LuaError::RuntimeError(format!(
|
||||||
"Expected argument #{} to be an EnumItem, got userdata",
|
"Expected argument #{index} to be an EnumItem, got userdata",
|
||||||
index
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
|
@ -4,14 +4,16 @@ use mlua::prelude::*;
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
use rbx_dom_weak::types::BrickColor as DomBrickColor;
|
use rbx_dom_weak::types::BrickColor as DomBrickColor;
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::{super::*, Color3};
|
use super::{super::*, Color3};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
An implementation of the [BrickColor](https://create.roblox.com/docs/reference/engine/datatypes/BrickColor) Roblox datatype.
|
An implementation of the [BrickColor](https://create.roblox.com/docs/reference/engine/datatypes/BrickColor) Roblox datatype.
|
||||||
|
|
||||||
This implements all documented properties, methods & constructors of the BrickColor class as of March 2023.
|
This implements all documented properties, methods & constructors of the `BrickColor` class as of March 2023.
|
||||||
*/
|
*/
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct BrickColor {
|
pub struct BrickColor {
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(clippy::items_after_statements)]
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use std::ops;
|
use std::ops;
|
||||||
|
|
||||||
|
@ -5,7 +7,9 @@ use glam::{EulerRot, Mat3, Mat4, Quat, Vec3};
|
||||||
use mlua::{prelude::*, Variadic};
|
use mlua::{prelude::*, Variadic};
|
||||||
use rbx_dom_weak::types::{CFrame as DomCFrame, Matrix3 as DomMatrix3, Vector3 as DomVector3};
|
use rbx_dom_weak::types::{CFrame as DomCFrame, Matrix3 as DomMatrix3, Vector3 as DomVector3};
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::{super::*, Vector3};
|
use super::{super::*, Vector3};
|
||||||
|
|
||||||
|
@ -14,7 +18,7 @@ use super::{super::*, Vector3};
|
||||||
Roblox datatype, backed by [`glam::Mat4`].
|
Roblox datatype, backed by [`glam::Mat4`].
|
||||||
|
|
||||||
This implements all documented properties, methods &
|
This implements all documented properties, methods &
|
||||||
constructors of the CFrame class as of March 2023.
|
constructors of the `CFrame` class as of March 2023.
|
||||||
*/
|
*/
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct CFrame(pub Mat4);
|
pub struct CFrame(pub Mat4);
|
||||||
|
@ -42,6 +46,7 @@ impl CFrame {
|
||||||
impl LuaExportsTable<'_> for CFrame {
|
impl LuaExportsTable<'_> for CFrame {
|
||||||
const EXPORT_NAME: &'static str = "CFrame";
|
const EXPORT_NAME: &'static str = "CFrame";
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_lines)]
|
||||||
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> {
|
fn create_exports_table(lua: &Lua) -> LuaResult<LuaTable> {
|
||||||
let cframe_angles = |_, (rx, ry, rz): (f32, f32, f32)| {
|
let cframe_angles = |_, (rx, ry, rz): (f32, f32, f32)| {
|
||||||
Ok(CFrame(Mat4::from_euler(EulerRot::XYZ, rx, ry, rz)))
|
Ok(CFrame(Mat4::from_euler(EulerRot::XYZ, rx, ry, rz)))
|
||||||
|
@ -68,8 +73,7 @@ impl LuaExportsTable<'_> for CFrame {
|
||||||
Ok(CFrame(Mat4::from_cols(
|
Ok(CFrame(Mat4::from_cols(
|
||||||
rx.0.extend(0.0),
|
rx.0.extend(0.0),
|
||||||
ry.0.extend(0.0),
|
ry.0.extend(0.0),
|
||||||
rz.map(|r| r.0)
|
rz.map_or_else(|| rx.0.cross(ry.0).normalize(), |r| r.0)
|
||||||
.unwrap_or_else(|| rx.0.cross(ry.0).normalize())
|
|
||||||
.extend(0.0),
|
.extend(0.0),
|
||||||
pos.0.extend(1.0),
|
pos.0.extend(1.0),
|
||||||
)))
|
)))
|
||||||
|
@ -195,6 +199,7 @@ impl LuaUserData for CFrame {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_lines)]
|
||||||
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
// Methods
|
// Methods
|
||||||
methods.add_method("Inverse", |_, this, ()| Ok(this.inverse()));
|
methods.add_method("Inverse", |_, this, ()| Ok(this.inverse()));
|
||||||
|
@ -226,34 +231,49 @@ impl LuaUserData for CFrame {
|
||||||
methods.add_method(
|
methods.add_method(
|
||||||
"ToWorldSpace",
|
"ToWorldSpace",
|
||||||
|_, this, rhs: Variadic<LuaUserDataRef<CFrame>>| {
|
|_, this, rhs: Variadic<LuaUserDataRef<CFrame>>| {
|
||||||
Ok(Variadic::from_iter(rhs.into_iter().map(|cf| *this * *cf)))
|
Ok(rhs
|
||||||
|
.into_iter()
|
||||||
|
.map(|cf| *this * *cf)
|
||||||
|
.collect::<Variadic<_>>())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
methods.add_method(
|
methods.add_method(
|
||||||
"ToObjectSpace",
|
"ToObjectSpace",
|
||||||
|_, this, rhs: Variadic<LuaUserDataRef<CFrame>>| {
|
|_, this, rhs: Variadic<LuaUserDataRef<CFrame>>| {
|
||||||
let inverse = this.inverse();
|
let inverse = this.inverse();
|
||||||
Ok(Variadic::from_iter(rhs.into_iter().map(|cf| inverse * *cf)))
|
Ok(rhs
|
||||||
|
.into_iter()
|
||||||
|
.map(|cf| inverse * *cf)
|
||||||
|
.collect::<Variadic<_>>())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
methods.add_method(
|
methods.add_method(
|
||||||
"PointToWorldSpace",
|
"PointToWorldSpace",
|
||||||
|_, this, rhs: Variadic<LuaUserDataRef<Vector3>>| {
|
|_, this, rhs: Variadic<LuaUserDataRef<Vector3>>| {
|
||||||
Ok(Variadic::from_iter(rhs.into_iter().map(|v3| *this * *v3)))
|
Ok(rhs
|
||||||
|
.into_iter()
|
||||||
|
.map(|v3| *this * *v3)
|
||||||
|
.collect::<Variadic<_>>())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
methods.add_method(
|
methods.add_method(
|
||||||
"PointToObjectSpace",
|
"PointToObjectSpace",
|
||||||
|_, this, rhs: Variadic<LuaUserDataRef<Vector3>>| {
|
|_, this, rhs: Variadic<LuaUserDataRef<Vector3>>| {
|
||||||
let inverse = this.inverse();
|
let inverse = this.inverse();
|
||||||
Ok(Variadic::from_iter(rhs.into_iter().map(|v3| inverse * *v3)))
|
Ok(rhs
|
||||||
|
.into_iter()
|
||||||
|
.map(|v3| inverse * *v3)
|
||||||
|
.collect::<Variadic<_>>())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
methods.add_method(
|
methods.add_method(
|
||||||
"VectorToWorldSpace",
|
"VectorToWorldSpace",
|
||||||
|_, this, rhs: Variadic<LuaUserDataRef<Vector3>>| {
|
|_, this, rhs: Variadic<LuaUserDataRef<Vector3>>| {
|
||||||
let result = *this - Vector3(this.position());
|
let result = *this - Vector3(this.position());
|
||||||
Ok(Variadic::from_iter(rhs.into_iter().map(|v3| result * *v3)))
|
Ok(rhs
|
||||||
|
.into_iter()
|
||||||
|
.map(|v3| result * *v3)
|
||||||
|
.collect::<Variadic<_>>())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
methods.add_method(
|
methods.add_method(
|
||||||
|
@ -261,8 +281,10 @@ impl LuaUserData for CFrame {
|
||||||
|_, this, rhs: Variadic<LuaUserDataRef<Vector3>>| {
|
|_, this, rhs: Variadic<LuaUserDataRef<Vector3>>| {
|
||||||
let inverse = this.inverse();
|
let inverse = this.inverse();
|
||||||
let result = inverse - Vector3(inverse.position());
|
let result = inverse - Vector3(inverse.position());
|
||||||
|
Ok(rhs
|
||||||
Ok(Variadic::from_iter(rhs.into_iter().map(|v3| result * *v3)))
|
.into_iter()
|
||||||
|
.map(|v3| result * *v3)
|
||||||
|
.collect::<Variadic<_>>())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
@ -445,7 +467,7 @@ mod cframe_test {
|
||||||
Vec3::new(1.0, 2.0, 3.0).extend(1.0),
|
Vec3::new(1.0, 2.0, 3.0).extend(1.0),
|
||||||
));
|
));
|
||||||
|
|
||||||
assert_eq!(CFrame::from(dom_cframe), cframe)
|
assert_eq!(CFrame::from(dom_cframe), cframe);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -466,6 +488,6 @@ mod cframe_test {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(DomCFrame::from(cframe), dom_cframe)
|
assert_eq!(DomCFrame::from(cframe), dom_cframe);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(clippy::many_single_char_names)]
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use std::ops;
|
use std::ops;
|
||||||
|
|
||||||
|
@ -5,7 +7,9 @@ use glam::Vec3;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::{Color3 as DomColor3, Color3uint8 as DomColor3uint8};
|
use rbx_dom_weak::types::{Color3 as DomColor3, Color3uint8 as DomColor3uint8};
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::super::*;
|
use super::super::*;
|
||||||
|
|
||||||
|
@ -85,8 +89,7 @@ impl LuaExportsTable<'_> for Color3 {
|
||||||
b: (b as f32) / 255f32,
|
b: (b as f32) / 255f32,
|
||||||
}),
|
}),
|
||||||
_ => Err(LuaError::RuntimeError(format!(
|
_ => Err(LuaError::RuntimeError(format!(
|
||||||
"Hex color string '{}' contains invalid character",
|
"Hex color string '{trimmed}' contains invalid character",
|
||||||
trimmed
|
|
||||||
))),
|
))),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -151,6 +154,7 @@ impl LuaUserData for Color3 {
|
||||||
let max = r.max(g).max(b);
|
let max = r.max(g).max(b);
|
||||||
let diff = max - min;
|
let diff = max - min;
|
||||||
|
|
||||||
|
#[allow(clippy::float_cmp)]
|
||||||
let hue = (match max {
|
let hue = (match max {
|
||||||
max if max == min => 0.0,
|
max if max == min => 0.0,
|
||||||
max if max == r => (g - b) / diff + (if g < b { 6.0 } else { 0.0 }),
|
max if max == r => (g - b) / diff + (if g < b { 6.0 } else { 0.0 }),
|
|
@ -5,14 +5,16 @@ use rbx_dom_weak::types::{
|
||||||
ColorSequence as DomColorSequence, ColorSequenceKeypoint as DomColorSequenceKeypoint,
|
ColorSequence as DomColorSequence, ColorSequenceKeypoint as DomColorSequenceKeypoint,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::{super::*, Color3, ColorSequenceKeypoint};
|
use super::{super::*, Color3, ColorSequenceKeypoint};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
An implementation of the [ColorSequence](https://create.roblox.com/docs/reference/engine/datatypes/ColorSequence) Roblox datatype.
|
An implementation of the [ColorSequence](https://create.roblox.com/docs/reference/engine/datatypes/ColorSequence) Roblox datatype.
|
||||||
|
|
||||||
This implements all documented properties, methods & constructors of the ColorSequence class as of March 2023.
|
This implements all documented properties, methods & constructors of the `ColorSequence` class as of March 2023.
|
||||||
*/
|
*/
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct ColorSequence {
|
pub struct ColorSequence {
|
||||||
|
@ -87,9 +89,9 @@ impl fmt::Display for ColorSequence {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
for (index, keypoint) in self.keypoints.iter().enumerate() {
|
for (index, keypoint) in self.keypoints.iter().enumerate() {
|
||||||
if index < self.keypoints.len() - 1 {
|
if index < self.keypoints.len() - 1 {
|
||||||
write!(f, "{}, ", keypoint)?;
|
write!(f, "{keypoint}, ")?;
|
||||||
} else {
|
} else {
|
||||||
write!(f, "{}", keypoint)?;
|
write!(f, "{keypoint}")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -102,7 +104,7 @@ impl From<DomColorSequence> for ColorSequence {
|
||||||
keypoints: v
|
keypoints: v
|
||||||
.keypoints
|
.keypoints
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.copied()
|
||||||
.map(ColorSequenceKeypoint::from)
|
.map(ColorSequenceKeypoint::from)
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
|
@ -115,7 +117,7 @@ impl From<ColorSequence> for DomColorSequence {
|
||||||
keypoints: v
|
keypoints: v
|
||||||
.keypoints
|
.keypoints
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.copied()
|
||||||
.map(DomColorSequenceKeypoint::from)
|
.map(DomColorSequenceKeypoint::from)
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
|
@ -3,14 +3,16 @@ use core::fmt;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::ColorSequenceKeypoint as DomColorSequenceKeypoint;
|
use rbx_dom_weak::types::ColorSequenceKeypoint as DomColorSequenceKeypoint;
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::{super::*, Color3};
|
use super::{super::*, Color3};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
An implementation of the [ColorSequenceKeypoint](https://create.roblox.com/docs/reference/engine/datatypes/ColorSequenceKeypoint) Roblox datatype.
|
An implementation of the [ColorSequenceKeypoint](https://create.roblox.com/docs/reference/engine/datatypes/ColorSequenceKeypoint) Roblox datatype.
|
||||||
|
|
||||||
This implements all documented properties, methods & constructors of the ColorSequenceKeypoint class as of March 2023.
|
This implements all documented properties, methods & constructors of the `ColorSequenceKeypoint` class as of March 2023.
|
||||||
*/
|
*/
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct ColorSequenceKeypoint {
|
pub struct ColorSequenceKeypoint {
|
|
@ -8,7 +8,7 @@ use super::{super::*, Enum};
|
||||||
/**
|
/**
|
||||||
An implementation of the [EnumItem](https://create.roblox.com/docs/reference/engine/datatypes/EnumItem) Roblox datatype.
|
An implementation of the [EnumItem](https://create.roblox.com/docs/reference/engine/datatypes/EnumItem) Roblox datatype.
|
||||||
|
|
||||||
This implements all documented properties, methods & constructors of the EnumItem class as of March 2023.
|
This implements all documented properties, methods & constructors of the `EnumItem` class as of March 2023.
|
||||||
*/
|
*/
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct EnumItem {
|
pub struct EnumItem {
|
|
@ -24,8 +24,7 @@ impl LuaUserData for Enums {
|
||||||
|_, _, name: String| match Enum::from_name(&name) {
|
|_, _, name: String| match Enum::from_name(&name) {
|
||||||
Some(e) => Ok(e),
|
Some(e) => Ok(e),
|
||||||
None => Err(LuaError::RuntimeError(format!(
|
None => Err(LuaError::RuntimeError(format!(
|
||||||
"The enum '{}' does not exist",
|
"The enum '{name}' does not exist",
|
||||||
name
|
|
||||||
))),
|
))),
|
||||||
},
|
},
|
||||||
);
|
);
|
|
@ -1,9 +1,13 @@
|
||||||
|
#![allow(clippy::struct_excessive_bools)]
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::Faces as DomFaces;
|
use rbx_dom_weak::types::Faces as DomFaces;
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::{super::*, EnumItem};
|
use super::{super::*, EnumItem};
|
||||||
|
|
||||||
|
@ -54,8 +58,7 @@ impl LuaExportsTable<'_> for Faces {
|
||||||
check(&e);
|
check(&e);
|
||||||
} else {
|
} else {
|
||||||
return Err(LuaError::RuntimeError(format!(
|
return Err(LuaError::RuntimeError(format!(
|
||||||
"Expected argument #{} to be an EnumItem, got userdata",
|
"Expected argument #{index} to be an EnumItem, got userdata",
|
||||||
index
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
|
@ -6,7 +6,9 @@ use rbx_dom_weak::types::{
|
||||||
Font as DomFont, FontStyle as DomFontStyle, FontWeight as DomFontWeight,
|
Font as DomFont, FontStyle as DomFontStyle, FontWeight as DomFontWeight,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::{super::*, EnumItem};
|
use super::{super::*, EnumItem};
|
||||||
|
|
||||||
|
@ -62,7 +64,7 @@ impl LuaExportsTable<'_> for Font {
|
||||||
let font_from_name =
|
let font_from_name =
|
||||||
|_, (file, weight, style): (String, Option<FontWeight>, Option<FontStyle>)| {
|
|_, (file, weight, style): (String, Option<FontWeight>, Option<FontStyle>)| {
|
||||||
Ok(Font {
|
Ok(Font {
|
||||||
family: format!("rbxasset://fonts/families/{}.json", file),
|
family: format!("rbxasset://fonts/families/{file}.json"),
|
||||||
weight: weight.unwrap_or_default(),
|
weight: weight.unwrap_or_default(),
|
||||||
style: style.unwrap_or_default(),
|
style: style.unwrap_or_default(),
|
||||||
cached_id: None,
|
cached_id: None,
|
||||||
|
@ -72,7 +74,7 @@ impl LuaExportsTable<'_> for Font {
|
||||||
let font_from_id =
|
let font_from_id =
|
||||||
|_, (id, weight, style): (i32, Option<FontWeight>, Option<FontStyle>)| {
|
|_, (id, weight, style): (i32, Option<FontWeight>, Option<FontStyle>)| {
|
||||||
Ok(Font {
|
Ok(Font {
|
||||||
family: format!("rbxassetid://{}", id),
|
family: format!("rbxassetid://{id}"),
|
||||||
weight: weight.unwrap_or_default(),
|
weight: weight.unwrap_or_default(),
|
||||||
style: style.unwrap_or_default(),
|
style: style.unwrap_or_default(),
|
||||||
cached_id: None,
|
cached_id: None,
|
||||||
|
@ -206,7 +208,7 @@ pub(crate) enum FontWeight {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FontWeight {
|
impl FontWeight {
|
||||||
pub(crate) fn as_u16(&self) -> u16 {
|
pub(crate) fn as_u16(self) -> u16 {
|
||||||
match self {
|
match self {
|
||||||
Self::Thin => 100,
|
Self::Thin => 100,
|
||||||
Self::ExtraLight => 200,
|
Self::ExtraLight => 200,
|
||||||
|
@ -288,12 +290,11 @@ impl<'lua> FromLua<'lua> for FontWeight {
|
||||||
if value.parent.desc.name == "FontWeight" {
|
if value.parent.desc.name == "FontWeight" {
|
||||||
if let Ok(value) = FontWeight::from_str(&value.name) {
|
if let Ok(value) = FontWeight::from_str(&value.name) {
|
||||||
return Ok(value);
|
return Ok(value);
|
||||||
} else {
|
}
|
||||||
message = Some(format!(
|
message = Some(format!(
|
||||||
"Found unknown Enum.FontWeight value '{}'",
|
"Found unknown Enum.FontWeight value '{}'",
|
||||||
value.name
|
value.name
|
||||||
));
|
));
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
message = Some(format!(
|
message = Some(format!(
|
||||||
"Expected Enum.FontWeight, got Enum.{}",
|
"Expected Enum.FontWeight, got Enum.{}",
|
||||||
|
@ -316,7 +317,7 @@ impl<'lua> IntoLua<'lua> for FontWeight {
|
||||||
None => Err(LuaError::ToLuaConversionError {
|
None => Err(LuaError::ToLuaConversionError {
|
||||||
from: "FontWeight",
|
from: "FontWeight",
|
||||||
to: "EnumItem",
|
to: "EnumItem",
|
||||||
message: Some(format!("Found unknown Enum.FontWeight value '{}'", self)),
|
message: Some(format!("Found unknown Enum.FontWeight value '{self}'")),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -329,7 +330,7 @@ pub(crate) enum FontStyle {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FontStyle {
|
impl FontStyle {
|
||||||
pub(crate) fn as_u8(&self) -> u8 {
|
pub(crate) fn as_u8(self) -> u8 {
|
||||||
match self {
|
match self {
|
||||||
Self::Normal => 0,
|
Self::Normal => 0,
|
||||||
Self::Italic => 1,
|
Self::Italic => 1,
|
||||||
|
@ -383,12 +384,11 @@ impl<'lua> FromLua<'lua> for FontStyle {
|
||||||
if value.parent.desc.name == "FontStyle" {
|
if value.parent.desc.name == "FontStyle" {
|
||||||
if let Ok(value) = FontStyle::from_str(&value.name) {
|
if let Ok(value) = FontStyle::from_str(&value.name) {
|
||||||
return Ok(value);
|
return Ok(value);
|
||||||
} else {
|
}
|
||||||
message = Some(format!(
|
message = Some(format!(
|
||||||
"Found unknown Enum.FontStyle value '{}'",
|
"Found unknown Enum.FontStyle value '{}'",
|
||||||
value.name
|
value.name
|
||||||
));
|
));
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
message = Some(format!(
|
message = Some(format!(
|
||||||
"Expected Enum.FontStyle, got Enum.{}",
|
"Expected Enum.FontStyle, got Enum.{}",
|
||||||
|
@ -411,7 +411,7 @@ impl<'lua> IntoLua<'lua> for FontStyle {
|
||||||
None => Err(LuaError::ToLuaConversionError {
|
None => Err(LuaError::ToLuaConversionError {
|
||||||
from: "FontStyle",
|
from: "FontStyle",
|
||||||
to: "EnumItem",
|
to: "EnumItem",
|
||||||
message: Some(format!("Found unknown Enum.FontStyle value '{}'", self)),
|
message: Some(format!("Found unknown Enum.FontStyle value '{self}'")),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,14 +3,16 @@ use core::fmt;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::NumberRange as DomNumberRange;
|
use rbx_dom_weak::types::NumberRange as DomNumberRange;
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::super::*;
|
use super::super::*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
An implementation of the [NumberRange](https://create.roblox.com/docs/reference/engine/datatypes/NumberRange) Roblox datatype.
|
An implementation of the [NumberRange](https://create.roblox.com/docs/reference/engine/datatypes/NumberRange) Roblox datatype.
|
||||||
|
|
||||||
This implements all documented properties, methods & constructors of the NumberRange class as of March 2023.
|
This implements all documented properties, methods & constructors of the `NumberRange` class as of March 2023.
|
||||||
*/
|
*/
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct NumberRange {
|
pub struct NumberRange {
|
|
@ -5,14 +5,16 @@ use rbx_dom_weak::types::{
|
||||||
NumberSequence as DomNumberSequence, NumberSequenceKeypoint as DomNumberSequenceKeypoint,
|
NumberSequence as DomNumberSequence, NumberSequenceKeypoint as DomNumberSequenceKeypoint,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::{super::*, NumberSequenceKeypoint};
|
use super::{super::*, NumberSequenceKeypoint};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
An implementation of the [NumberSequence](https://create.roblox.com/docs/reference/engine/datatypes/NumberSequence) Roblox datatype.
|
An implementation of the [NumberSequence](https://create.roblox.com/docs/reference/engine/datatypes/NumberSequence) Roblox datatype.
|
||||||
|
|
||||||
This implements all documented properties, methods & constructors of the NumberSequence class as of March 2023.
|
This implements all documented properties, methods & constructors of the `NumberSequence` class as of March 2023.
|
||||||
*/
|
*/
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct NumberSequence {
|
pub struct NumberSequence {
|
||||||
|
@ -91,9 +93,9 @@ impl fmt::Display for NumberSequence {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
for (index, keypoint) in self.keypoints.iter().enumerate() {
|
for (index, keypoint) in self.keypoints.iter().enumerate() {
|
||||||
if index < self.keypoints.len() - 1 {
|
if index < self.keypoints.len() - 1 {
|
||||||
write!(f, "{}, ", keypoint)?;
|
write!(f, "{keypoint}, ")?;
|
||||||
} else {
|
} else {
|
||||||
write!(f, "{}", keypoint)?;
|
write!(f, "{keypoint}")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -106,7 +108,7 @@ impl From<DomNumberSequence> for NumberSequence {
|
||||||
keypoints: v
|
keypoints: v
|
||||||
.keypoints
|
.keypoints
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.copied()
|
||||||
.map(NumberSequenceKeypoint::from)
|
.map(NumberSequenceKeypoint::from)
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
|
@ -119,7 +121,7 @@ impl From<NumberSequence> for DomNumberSequence {
|
||||||
keypoints: v
|
keypoints: v
|
||||||
.keypoints
|
.keypoints
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.copied()
|
||||||
.map(DomNumberSequenceKeypoint::from)
|
.map(DomNumberSequenceKeypoint::from)
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
|
@ -3,14 +3,16 @@ use core::fmt;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::NumberSequenceKeypoint as DomNumberSequenceKeypoint;
|
use rbx_dom_weak::types::NumberSequenceKeypoint as DomNumberSequenceKeypoint;
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::super::*;
|
use super::super::*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
An implementation of the [NumberSequenceKeypoint](https://create.roblox.com/docs/reference/engine/datatypes/NumberSequenceKeypoint) Roblox datatype.
|
An implementation of the [NumberSequenceKeypoint](https://create.roblox.com/docs/reference/engine/datatypes/NumberSequenceKeypoint) Roblox datatype.
|
||||||
|
|
||||||
This implements all documented properties, methods & constructors of the NumberSequenceKeypoint class as of March 2023.
|
This implements all documented properties, methods & constructors of the `NumberSequenceKeypoint` class as of March 2023.
|
||||||
*/
|
*/
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct NumberSequenceKeypoint {
|
pub struct NumberSequenceKeypoint {
|
|
@ -3,14 +3,16 @@ use core::fmt;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::CustomPhysicalProperties as DomCustomPhysicalProperties;
|
use rbx_dom_weak::types::CustomPhysicalProperties as DomCustomPhysicalProperties;
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::{super::*, EnumItem};
|
use super::{super::*, EnumItem};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
An implementation of the [PhysicalProperties](https://create.roblox.com/docs/reference/engine/datatypes/PhysicalProperties) Roblox datatype.
|
An implementation of the [PhysicalProperties](https://create.roblox.com/docs/reference/engine/datatypes/PhysicalProperties) Roblox datatype.
|
||||||
|
|
||||||
This implements all documented properties, methods & constructors of the PhysicalProperties class as of March 2023.
|
This implements all documented properties, methods & constructors of the `PhysicalProperties` class as of March 2023.
|
||||||
*/
|
*/
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct PhysicalProperties {
|
pub struct PhysicalProperties {
|
|
@ -4,7 +4,9 @@ use glam::Vec3;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::Ray as DomRay;
|
use rbx_dom_weak::types::Ray as DomRay;
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::{super::*, Vector3};
|
use super::{super::*, Vector3};
|
||||||
|
|
|
@ -5,7 +5,9 @@ use glam::Vec2;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::Rect as DomRect;
|
use rbx_dom_weak::types::Rect as DomRect;
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::{super::*, Vector2};
|
use super::{super::*, Vector2};
|
||||||
|
|
|
@ -4,7 +4,9 @@ use glam::{Mat4, Vec3};
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::Region3 as DomRegion3;
|
use rbx_dom_weak::types::Region3 as DomRegion3;
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::{super::*, CFrame, Vector3};
|
use super::{super::*, CFrame, Vector3};
|
||||||
|
|
|
@ -4,7 +4,9 @@ use glam::IVec3;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::Region3int16 as DomRegion3int16;
|
use rbx_dom_weak::types::Region3int16 as DomRegion3int16;
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::{super::*, Vector3int16};
|
use super::{super::*, Vector3int16};
|
||||||
|
|
|
@ -4,14 +4,16 @@ use std::ops;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::UDim as DomUDim;
|
use rbx_dom_weak::types::UDim as DomUDim;
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::super::*;
|
use super::super::*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
An implementation of the [UDim](https://create.roblox.com/docs/reference/engine/datatypes/UDim) Roblox datatype.
|
An implementation of the [UDim](https://create.roblox.com/docs/reference/engine/datatypes/UDim) Roblox datatype.
|
||||||
|
|
||||||
This implements all documented properties, methods & constructors of the UDim class as of March 2023.
|
This implements all documented properties, methods & constructors of the `UDim` class as of March 2023.
|
||||||
*/
|
*/
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct UDim {
|
pub struct UDim {
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(clippy::items_after_statements)]
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use std::ops;
|
use std::ops;
|
||||||
|
|
||||||
|
@ -5,14 +7,16 @@ use glam::Vec2;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::UDim2 as DomUDim2;
|
use rbx_dom_weak::types::UDim2 as DomUDim2;
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::{super::*, UDim};
|
use super::{super::*, UDim};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
An implementation of the [UDim2](https://create.roblox.com/docs/reference/engine/datatypes/UDim2) Roblox datatype.
|
An implementation of the [UDim2](https://create.roblox.com/docs/reference/engine/datatypes/UDim2) Roblox datatype.
|
||||||
|
|
||||||
This implements all documented properties, methods & constructors of the UDim2 class as of March 2023.
|
This implements all documented properties, methods & constructors of the `UDim2` class as of March 2023.
|
||||||
*/
|
*/
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct UDim2 {
|
pub struct UDim2 {
|
|
@ -5,7 +5,9 @@ use glam::{Vec2, Vec3};
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::Vector2 as DomVector2;
|
use rbx_dom_weak::types::Vector2 as DomVector2;
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::super::*;
|
use super::super::*;
|
||||||
|
|
|
@ -5,7 +5,9 @@ use glam::IVec2;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::Vector2int16 as DomVector2int16;
|
use rbx_dom_weak::types::Vector2int16 as DomVector2int16;
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::super::*;
|
use super::super::*;
|
||||||
|
|
|
@ -5,10 +5,9 @@ use glam::Vec3;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::Vector3 as DomVector3;
|
use rbx_dom_weak::types::Vector3 as DomVector3;
|
||||||
|
|
||||||
use crate::{
|
use lune_utils::TableBuilder;
|
||||||
lune::util::TableBuilder,
|
|
||||||
roblox::{datatypes::util::round_float_decimal, exports::LuaExportsTable},
|
use crate::{datatypes::util::round_float_decimal, exports::LuaExportsTable};
|
||||||
};
|
|
||||||
|
|
||||||
use super::{super::*, EnumItem};
|
use super::{super::*, EnumItem};
|
||||||
|
|
||||||
|
@ -37,8 +36,7 @@ impl LuaExportsTable<'_> for Vector3 {
|
||||||
"Z" => Vector3(Vec3::Z),
|
"Z" => Vector3(Vec3::Z),
|
||||||
name => {
|
name => {
|
||||||
return Err(LuaError::RuntimeError(format!(
|
return Err(LuaError::RuntimeError(format!(
|
||||||
"Axis '{}' is not known",
|
"Axis '{name}' is not known",
|
||||||
name
|
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -61,8 +59,7 @@ impl LuaExportsTable<'_> for Vector3 {
|
||||||
"Back" => Vector3(Vec3::Z),
|
"Back" => Vector3(Vec3::Z),
|
||||||
name => {
|
name => {
|
||||||
return Err(LuaError::RuntimeError(format!(
|
return Err(LuaError::RuntimeError(format!(
|
||||||
"NormalId '{}' is not known",
|
"NormalId '{name}' is not known",
|
||||||
name
|
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
})
|
})
|
|
@ -5,7 +5,9 @@ use glam::IVec3;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::Vector3int16 as DomVector3int16;
|
use rbx_dom_weak::types::Vector3int16 as DomVector3int16;
|
||||||
|
|
||||||
use crate::{lune::util::TableBuilder, roblox::exports::LuaExportsTable};
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
use crate::exports::LuaExportsTable;
|
||||||
|
|
||||||
use super::super::*;
|
use super::super::*;
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::path::Path;
|
||||||
|
|
||||||
use rbx_dom_weak::WeakDom;
|
use rbx_dom_weak::WeakDom;
|
||||||
|
|
||||||
use crate::roblox::shared::instance::class_is_a_service;
|
use crate::shared::instance::class_is_a_service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A document kind specifier.
|
A document kind specifier.
|
||||||
|
@ -58,6 +58,7 @@ impl DocumentKind {
|
||||||
|
|
||||||
Returns `None` if the given dom is empty and as such can not have its kind inferred.
|
Returns `None` if the given dom is empty and as such can not have its kind inferred.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn from_weak_dom(dom: &WeakDom) -> Option<Self> {
|
pub fn from_weak_dom(dom: &WeakDom) -> Option<Self> {
|
||||||
let mut has_top_level_child = false;
|
let mut has_top_level_child = false;
|
||||||
let mut has_top_level_service = false;
|
let mut has_top_level_service = false;
|
|
@ -15,7 +15,7 @@ pub use kind::*;
|
||||||
|
|
||||||
use postprocessing::*;
|
use postprocessing::*;
|
||||||
|
|
||||||
use crate::roblox::instance::{data_model, Instance};
|
use crate::instance::{data_model, Instance};
|
||||||
|
|
||||||
pub type DocumentResult<T> = Result<T, DocumentError>;
|
pub type DocumentResult<T> = Result<T, DocumentError>;
|
||||||
|
|
||||||
|
@ -78,6 +78,7 @@ impl Document {
|
||||||
| Model | Binary | `rbxm` |
|
| Model | Binary | `rbxm` |
|
||||||
| Model | Xml | `rbxmx` |
|
| Model | Xml | `rbxmx` |
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub fn canonical_extension(kind: DocumentKind, format: DocumentFormat) -> &'static str {
|
pub fn canonical_extension(kind: DocumentKind, format: DocumentFormat) -> &'static str {
|
||||||
match (kind, format) {
|
match (kind, format) {
|
||||||
|
@ -113,6 +114,10 @@ impl Document {
|
||||||
Note that detection of model vs place file is heavily dependent on the structure
|
Note that detection of model vs place file is heavily dependent on the structure
|
||||||
of the file, and a model file with services in it will detect as a place file, so
|
of the file, and a model file with services in it will detect as a place file, so
|
||||||
if possible using [`Document::from_bytes`] with an explicit kind should be preferred.
|
if possible using [`Document::from_bytes`] with an explicit kind should be preferred.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
Errors if the given bytes are not a valid roblox file.
|
||||||
*/
|
*/
|
||||||
pub fn from_bytes_auto(bytes: impl AsRef<[u8]>) -> DocumentResult<Self> {
|
pub fn from_bytes_auto(bytes: impl AsRef<[u8]>) -> DocumentResult<Self> {
|
||||||
let (format, dom) = Self::from_bytes_inner(bytes)?;
|
let (format, dom) = Self::from_bytes_inner(bytes)?;
|
||||||
|
@ -125,6 +130,10 @@ impl Document {
|
||||||
|
|
||||||
This will automatically handle and detect if the document
|
This will automatically handle and detect if the document
|
||||||
should be decoded using a roblox binary or roblox xml format.
|
should be decoded using a roblox binary or roblox xml format.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
Errors if the given bytes are not a valid roblox file or not of the given kind.
|
||||||
*/
|
*/
|
||||||
pub fn from_bytes(bytes: impl AsRef<[u8]>, kind: DocumentKind) -> DocumentResult<Self> {
|
pub fn from_bytes(bytes: impl AsRef<[u8]>, kind: DocumentKind) -> DocumentResult<Self> {
|
||||||
let (format, dom) = Self::from_bytes_inner(bytes)?;
|
let (format, dom) = Self::from_bytes_inner(bytes)?;
|
||||||
|
@ -138,6 +147,10 @@ impl Document {
|
||||||
This will use the same format that the document was created
|
This will use the same format that the document was created
|
||||||
with, meaning if the document is a binary document the output
|
with, meaning if the document is a binary document the output
|
||||||
will be binary, and vice versa for xml and other future formats.
|
will be binary, and vice versa for xml and other future formats.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
Errors if the document can not be encoded.
|
||||||
*/
|
*/
|
||||||
pub fn to_bytes(&self) -> DocumentResult<Vec<u8>> {
|
pub fn to_bytes(&self) -> DocumentResult<Vec<u8>> {
|
||||||
self.to_bytes_with_format(self.format)
|
self.to_bytes_with_format(self.format)
|
||||||
|
@ -146,6 +159,10 @@ impl Document {
|
||||||
/**
|
/**
|
||||||
Encodes the document as a vector of bytes, to
|
Encodes the document as a vector of bytes, to
|
||||||
be written to a file or sent over the network.
|
be written to a file or sent over the network.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
Errors if the document can not be encoded.
|
||||||
*/
|
*/
|
||||||
pub fn to_bytes_with_format(&self, format: DocumentFormat) -> DocumentResult<Vec<u8>> {
|
pub fn to_bytes_with_format(&self, format: DocumentFormat) -> DocumentResult<Vec<u8>> {
|
||||||
let mut bytes = Vec::new();
|
let mut bytes = Vec::new();
|
||||||
|
@ -172,6 +189,7 @@ impl Document {
|
||||||
/**
|
/**
|
||||||
Gets the kind this document was created with.
|
Gets the kind this document was created with.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn kind(&self) -> DocumentKind {
|
pub fn kind(&self) -> DocumentKind {
|
||||||
self.kind
|
self.kind
|
||||||
}
|
}
|
||||||
|
@ -179,6 +197,7 @@ impl Document {
|
||||||
/**
|
/**
|
||||||
Gets the format this document was created with.
|
Gets the format this document was created with.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn format(&self) -> DocumentFormat {
|
pub fn format(&self) -> DocumentFormat {
|
||||||
self.format
|
self.format
|
||||||
}
|
}
|
||||||
|
@ -186,14 +205,17 @@ impl Document {
|
||||||
/**
|
/**
|
||||||
Gets the file extension for this document.
|
Gets the file extension for this document.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn extension(&self) -> &'static str {
|
pub fn extension(&self) -> &'static str {
|
||||||
Self::canonical_extension(self.kind, self.format)
|
Self::canonical_extension(self.kind, self.format)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a DataModel instance out of this place document.
|
Creates a `DataModel` instance out of this place document.
|
||||||
|
|
||||||
Will error if the document is not a place.
|
# Errors
|
||||||
|
|
||||||
|
Errors if the document is not a place.
|
||||||
*/
|
*/
|
||||||
pub fn into_data_model_instance(mut self) -> DocumentResult<Instance> {
|
pub fn into_data_model_instance(mut self) -> DocumentResult<Instance> {
|
||||||
if self.kind != DocumentKind::Place {
|
if self.kind != DocumentKind::Place {
|
||||||
|
@ -219,7 +241,9 @@ impl Document {
|
||||||
/**
|
/**
|
||||||
Creates an array of instances out of this model document.
|
Creates an array of instances out of this model document.
|
||||||
|
|
||||||
Will error if the document is not a model.
|
# Errors
|
||||||
|
|
||||||
|
Errors if the document is not a model.
|
||||||
*/
|
*/
|
||||||
pub fn into_instance_array(mut self) -> DocumentResult<Vec<Instance>> {
|
pub fn into_instance_array(mut self) -> DocumentResult<Vec<Instance>> {
|
||||||
if self.kind != DocumentKind::Model {
|
if self.kind != DocumentKind::Model {
|
||||||
|
@ -237,9 +261,11 @@ impl Document {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a place document out of a DataModel instance.
|
Creates a place document out of a `DataModel` instance.
|
||||||
|
|
||||||
Will error if the instance is not a DataModel.
|
# Errors
|
||||||
|
|
||||||
|
Errors if the instance is not a `DataModel`.
|
||||||
*/
|
*/
|
||||||
pub fn from_data_model_instance(i: Instance) -> DocumentResult<Self> {
|
pub fn from_data_model_instance(i: Instance) -> DocumentResult<Self> {
|
||||||
if i.get_class_name() != data_model::CLASS_NAME {
|
if i.get_class_name() != data_model::CLASS_NAME {
|
||||||
|
@ -266,7 +292,9 @@ impl Document {
|
||||||
/**
|
/**
|
||||||
Creates a model document out of an array of instances.
|
Creates a model document out of an array of instances.
|
||||||
|
|
||||||
Will error if any of the instances is a DataModel.
|
# Errors
|
||||||
|
|
||||||
|
Errors if any of the instances is a `DataModel`.
|
||||||
*/
|
*/
|
||||||
pub fn from_instance_array(v: Vec<Instance>) -> DocumentResult<Self> {
|
pub fn from_instance_array(v: Vec<Instance>) -> DocumentResult<Self> {
|
||||||
for i in &v {
|
for i in &v {
|
|
@ -3,7 +3,7 @@ use rbx_dom_weak::{
|
||||||
Instance as DomInstance, WeakDom,
|
Instance as DomInstance, WeakDom,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::roblox::shared::instance::class_is_a;
|
use crate::shared::instance::class_is_a;
|
||||||
|
|
||||||
pub fn postprocess_dom_for_place(_dom: &mut WeakDom) {
|
pub fn postprocess_dom_for_place(_dom: &mut WeakDom) {
|
||||||
// Nothing here yet
|
// Nothing here yet
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(clippy::items_after_statements)]
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use rbx_dom_weak::{
|
use rbx_dom_weak::{
|
||||||
|
@ -5,7 +7,7 @@ use rbx_dom_weak::{
|
||||||
Instance as DomInstance,
|
Instance as DomInstance,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::roblox::{
|
use crate::{
|
||||||
datatypes::{
|
datatypes::{
|
||||||
attributes::{ensure_valid_attribute_name, ensure_valid_attribute_value},
|
attributes::{ensure_valid_attribute_name, ensure_valid_attribute_value},
|
||||||
conversion::{DomValueToLua, LuaToDomValue},
|
conversion::{DomValueToLua, LuaToDomValue},
|
||||||
|
@ -17,6 +19,7 @@ use crate::roblox::{
|
||||||
|
|
||||||
use super::{data_model, registry::InstanceRegistry, Instance};
|
use super::{data_model, registry::InstanceRegistry, Instance};
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_lines)]
|
||||||
pub fn add_methods<'lua, M: LuaUserDataMethods<'lua, Instance>>(m: &mut M) {
|
pub fn add_methods<'lua, M: LuaUserDataMethods<'lua, Instance>>(m: &mut M) {
|
||||||
m.add_meta_method(LuaMetaMethod::ToString, |lua, this, ()| {
|
m.add_meta_method(LuaMetaMethod::ToString, |lua, this, ()| {
|
||||||
ensure_not_destroyed(this)?;
|
ensure_not_destroyed(this)?;
|
||||||
|
@ -142,7 +145,7 @@ pub fn add_methods<'lua, M: LuaUserDataMethods<'lua, Instance>>(m: &mut M) {
|
||||||
ensure_not_destroyed(this)?;
|
ensure_not_destroyed(this)?;
|
||||||
let attributes = this.get_attributes();
|
let attributes = this.get_attributes();
|
||||||
let tab = lua.create_table_with_capacity(0, attributes.len())?;
|
let tab = lua.create_table_with_capacity(0, attributes.len())?;
|
||||||
for (key, value) in attributes.into_iter() {
|
for (key, value) in attributes {
|
||||||
tab.set(key, LuaValue::dom_value_to_lua(lua, &value)?)?;
|
tab.set(key, LuaValue::dom_value_to_lua(lua, &value)?)?;
|
||||||
}
|
}
|
||||||
Ok(tab)
|
Ok(tab)
|
||||||
|
@ -227,8 +230,7 @@ fn instance_property_get<'lua>(
|
||||||
if let DomValue::Enum(enum_value) = prop {
|
if let DomValue::Enum(enum_value) = prop {
|
||||||
let enum_name = info.enum_name.ok_or_else(|| {
|
let enum_name = info.enum_name.ok_or_else(|| {
|
||||||
LuaError::RuntimeError(format!(
|
LuaError::RuntimeError(format!(
|
||||||
"Failed to get property '{}' - encountered unknown enum",
|
"Failed to get property '{prop_name}' - encountered unknown enum",
|
||||||
prop_name
|
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
EnumItem::from_enum_name_and_value(&enum_name, enum_value.to_u32())
|
EnumItem::from_enum_name_and_value(&enum_name, enum_value.to_u32())
|
||||||
|
@ -246,8 +248,7 @@ fn instance_property_get<'lua>(
|
||||||
EnumItem::from_enum_name_and_value(&enum_name, enum_value)
|
EnumItem::from_enum_name_and_value(&enum_name, enum_value)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
LuaError::RuntimeError(format!(
|
LuaError::RuntimeError(format!(
|
||||||
"Failed to get property '{}' - Enum.{} does not contain numeric value {}",
|
"Failed to get property '{prop_name}' - Enum.{enum_name} does not contain numeric value {enum_value}",
|
||||||
prop_name, enum_name, enum_value
|
|
||||||
))
|
))
|
||||||
})?
|
})?
|
||||||
.into_lua(lua)
|
.into_lua(lua)
|
||||||
|
@ -258,14 +259,12 @@ fn instance_property_get<'lua>(
|
||||||
Ok(LuaValue::Nil)
|
Ok(LuaValue::Nil)
|
||||||
} else {
|
} else {
|
||||||
Err(LuaError::RuntimeError(format!(
|
Err(LuaError::RuntimeError(format!(
|
||||||
"Failed to get property '{}' - missing default value",
|
"Failed to get property '{prop_name}' - missing default value",
|
||||||
prop_name
|
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(LuaError::RuntimeError(format!(
|
Err(LuaError::RuntimeError(format!(
|
||||||
"Failed to get property '{}' - malformed property info",
|
"Failed to get property '{prop_name}' - malformed property info",
|
||||||
prop_name
|
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
} else if let Some(inst) = this.find_child(|inst| inst.name == prop_name) {
|
} else if let Some(inst) = this.find_child(|inst| inst.name == prop_name) {
|
||||||
|
@ -276,8 +275,7 @@ fn instance_property_get<'lua>(
|
||||||
Ok(LuaValue::Function(method))
|
Ok(LuaValue::Function(method))
|
||||||
} else {
|
} else {
|
||||||
Err(LuaError::RuntimeError(format!(
|
Err(LuaError::RuntimeError(format!(
|
||||||
"{} is not a valid member of {}",
|
"{prop_name} is not a valid member of {this}",
|
||||||
prop_name, this
|
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,16 +345,14 @@ fn instance_property_set<'lua>(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(LuaError::RuntimeError(format!(
|
Err(LuaError::RuntimeError(format!(
|
||||||
"Failed to set property '{}' - malformed property info",
|
"Failed to set property '{prop_name}' - malformed property info",
|
||||||
prop_name
|
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
} else if let Some(setter) = InstanceRegistry::find_property_setter(lua, this, &prop_name) {
|
} else if let Some(setter) = InstanceRegistry::find_property_setter(lua, this, &prop_name) {
|
||||||
setter.call((this.clone(), prop_value))
|
setter.call((this.clone(), prop_value))
|
||||||
} else {
|
} else {
|
||||||
Err(LuaError::RuntimeError(format!(
|
Err(LuaError::RuntimeError(format!(
|
||||||
"{} is not a valid member of {}",
|
"{prop_name} is not a valid member of {this}",
|
||||||
prop_name, this
|
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use crate::roblox::shared::{
|
use crate::shared::{
|
||||||
classes::{
|
classes::{
|
||||||
add_class_restricted_getter, add_class_restricted_method,
|
add_class_restricted_getter, add_class_restricted_method,
|
||||||
get_or_create_property_ref_instance,
|
get_or_create_property_ref_instance,
|
||||||
|
@ -33,7 +33,7 @@ fn data_model_get_workspace(_: &Lua, this: &Instance) -> LuaResult<Instance> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Gets or creates a service for this DataModel.
|
Gets or creates a service for this `DataModel`.
|
||||||
|
|
||||||
### See Also
|
### See Also
|
||||||
* [`GetService`](https://create.roblox.com/docs/reference/engine/classes/ServiceProvider#GetService)
|
* [`GetService`](https://create.roblox.com/docs/reference/engine/classes/ServiceProvider#GetService)
|
||||||
|
@ -42,8 +42,7 @@ fn data_model_get_workspace(_: &Lua, this: &Instance) -> LuaResult<Instance> {
|
||||||
fn data_model_get_service(_: &Lua, this: &Instance, service_name: String) -> LuaResult<Instance> {
|
fn data_model_get_service(_: &Lua, this: &Instance, service_name: String) -> LuaResult<Instance> {
|
||||||
if matches!(class_is_a_service(&service_name), None | Some(false)) {
|
if matches!(class_is_a_service(&service_name), None | Some(false)) {
|
||||||
Err(LuaError::RuntimeError(format!(
|
Err(LuaError::RuntimeError(format!(
|
||||||
"'{}' is not a valid service name",
|
"'{service_name}' is not a valid service name",
|
||||||
service_name
|
|
||||||
)))
|
)))
|
||||||
} else if let Some(service) = this.find_child(|child| child.class == service_name) {
|
} else if let Some(service) = this.find_child(|child| child.class == service_name) {
|
||||||
Ok(service)
|
Ok(service)
|
||||||
|
@ -55,7 +54,7 @@ fn data_model_get_service(_: &Lua, this: &Instance, service_name: String) -> Lua
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Gets a service for this DataModel, if it exists.
|
Gets a service for this `DataModel`, if it exists.
|
||||||
|
|
||||||
### See Also
|
### See Also
|
||||||
* [`FindService`](https://create.roblox.com/docs/reference/engine/classes/ServiceProvider#FindService)
|
* [`FindService`](https://create.roblox.com/docs/reference/engine/classes/ServiceProvider#FindService)
|
||||||
|
@ -68,8 +67,7 @@ fn data_model_find_service(
|
||||||
) -> LuaResult<Option<Instance>> {
|
) -> LuaResult<Option<Instance>> {
|
||||||
if matches!(class_is_a_service(&service_name), None | Some(false)) {
|
if matches!(class_is_a_service(&service_name), None | Some(false)) {
|
||||||
Err(LuaError::RuntimeError(format!(
|
Err(LuaError::RuntimeError(format!(
|
||||||
"'{}' is not a valid service name",
|
"'{service_name}' is not a valid service name",
|
||||||
service_name
|
|
||||||
)))
|
)))
|
||||||
} else if let Some(service) = this.find_child(|child| child.class == service_name) {
|
} else if let Some(service) = this.find_child(|child| child.class == service_name) {
|
||||||
Ok(Some(service))
|
Ok(Some(service))
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(clippy::missing_panics_doc)]
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::{BTreeMap, VecDeque},
|
collections::{BTreeMap, VecDeque},
|
||||||
fmt,
|
fmt,
|
||||||
|
@ -12,10 +14,11 @@ use rbx_dom_weak::{
|
||||||
Instance as DomInstance, InstanceBuilder as DomInstanceBuilder, WeakDom,
|
Instance as DomInstance, InstanceBuilder as DomInstanceBuilder, WeakDom,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
lune::util::TableBuilder,
|
exports::LuaExportsTable,
|
||||||
roblox::exports::LuaExportsTable,
|
shared::instance::{class_exists, class_is_a},
|
||||||
roblox::shared::instance::{class_exists, class_is_a},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) mod base;
|
pub(crate) mod base;
|
||||||
|
@ -54,9 +57,10 @@ impl Instance {
|
||||||
.get_by_ref(dom_ref)
|
.get_by_ref(dom_ref)
|
||||||
.expect("Failed to find instance in document");
|
.expect("Failed to find instance in document");
|
||||||
|
|
||||||
if instance.referent() == dom.root_ref() {
|
assert!(
|
||||||
panic!("Instances can not be created from dom roots")
|
!(instance.referent() == dom.root_ref()),
|
||||||
}
|
"Instances can not be created from dom roots"
|
||||||
|
);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
dom_ref,
|
dom_ref,
|
||||||
|
@ -76,9 +80,10 @@ impl Instance {
|
||||||
let dom = INTERNAL_DOM.lock().expect("Failed to lock document");
|
let dom = INTERNAL_DOM.lock().expect("Failed to lock document");
|
||||||
|
|
||||||
if let Some(instance) = dom.get_by_ref(dom_ref) {
|
if let Some(instance) = dom.get_by_ref(dom_ref) {
|
||||||
if instance.referent() == dom.root_ref() {
|
assert!(
|
||||||
panic!("Instances can not be created from dom roots")
|
!(instance.referent() == dom.root_ref()),
|
||||||
}
|
"Instances can not be created from dom roots"
|
||||||
|
);
|
||||||
|
|
||||||
Some(Self {
|
Some(Self {
|
||||||
dom_ref,
|
dom_ref,
|
||||||
|
@ -154,7 +159,7 @@ impl Instance {
|
||||||
|
|
||||||
let cloned = dom.clone_multiple_into_external(referents, external_dom);
|
let cloned = dom.clone_multiple_into_external(referents, external_dom);
|
||||||
|
|
||||||
for referent in cloned.iter() {
|
for referent in &cloned {
|
||||||
external_dom.transfer_within(*referent, external_dom.root_ref());
|
external_dom.transfer_within(*referent, external_dom.root_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +176,8 @@ impl Instance {
|
||||||
* [`Clone`](https://create.roblox.com/docs/reference/engine/classes/Instance#Clone)
|
* [`Clone`](https://create.roblox.com/docs/reference/engine/classes/Instance#Clone)
|
||||||
on the Roblox Developer Hub
|
on the Roblox Developer Hub
|
||||||
*/
|
*/
|
||||||
pub fn clone_instance(&self) -> Instance {
|
#[must_use]
|
||||||
|
pub fn clone_instance(&self) -> Self {
|
||||||
let mut dom = INTERNAL_DOM.lock().expect("Failed to lock document");
|
let mut dom = INTERNAL_DOM.lock().expect("Failed to lock document");
|
||||||
let new_ref = dom.clone_within(self.dom_ref);
|
let new_ref = dom.clone_within(self.dom_ref);
|
||||||
drop(dom); // Self::new needs mutex handle, drop it first
|
drop(dom); // Self::new needs mutex handle, drop it first
|
||||||
|
@ -254,6 +260,7 @@ impl Instance {
|
||||||
* [`ClassName`](https://create.roblox.com/docs/reference/engine/classes/Instance#ClassName)
|
* [`ClassName`](https://create.roblox.com/docs/reference/engine/classes/Instance#ClassName)
|
||||||
on the Roblox Developer Hub
|
on the Roblox Developer Hub
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn get_class_name(&self) -> &str {
|
pub fn get_class_name(&self) -> &str {
|
||||||
self.class_name.as_str()
|
self.class_name.as_str()
|
||||||
}
|
}
|
||||||
|
@ -286,7 +293,7 @@ impl Instance {
|
||||||
|
|
||||||
dom.get_by_ref_mut(self.dom_ref)
|
dom.get_by_ref_mut(self.dom_ref)
|
||||||
.expect("Failed to find instance in document")
|
.expect("Failed to find instance in document")
|
||||||
.name = name.into()
|
.name = name.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -326,9 +333,7 @@ impl Instance {
|
||||||
pub fn set_parent(&self, parent: Option<Instance>) {
|
pub fn set_parent(&self, parent: Option<Instance>) {
|
||||||
let mut dom = INTERNAL_DOM.lock().expect("Failed to lock document");
|
let mut dom = INTERNAL_DOM.lock().expect("Failed to lock document");
|
||||||
|
|
||||||
let parent_ref = parent
|
let parent_ref = parent.map_or_else(|| dom.root_ref(), |parent| parent.dom_ref);
|
||||||
.map(|parent| parent.dom_ref)
|
|
||||||
.unwrap_or_else(|| dom.root_ref());
|
|
||||||
|
|
||||||
dom.transfer_within(self.dom_ref, parent_ref);
|
dom.transfer_within(self.dom_ref, parent_ref);
|
||||||
}
|
}
|
||||||
|
@ -663,9 +668,8 @@ impl Instance {
|
||||||
if predicate(ancestor) {
|
if predicate(ancestor) {
|
||||||
drop(dom); // Self::new needs mutex handle, drop it first
|
drop(dom); // Self::new needs mutex handle, drop it first
|
||||||
return Some(Self::new(ancestor_ref));
|
return Some(Self::new(ancestor_ref));
|
||||||
} else {
|
|
||||||
ancestor_ref = ancestor.parent();
|
|
||||||
}
|
}
|
||||||
|
ancestor_ref = ancestor.parent();
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
|
@ -699,9 +703,8 @@ impl Instance {
|
||||||
let queue_ref = queue_item.referent();
|
let queue_ref = queue_item.referent();
|
||||||
drop(dom); // Self::new needs mutex handle, drop it first
|
drop(dom); // Self::new needs mutex handle, drop it first
|
||||||
return Some(Self::new(queue_ref));
|
return Some(Self::new(queue_ref));
|
||||||
} else {
|
|
||||||
queue.extend(queue_item.children())
|
|
||||||
}
|
}
|
||||||
|
queue.extend(queue_item.children());
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
|
@ -717,8 +720,7 @@ impl LuaExportsTable<'_> for Instance {
|
||||||
Instance::new_orphaned(class_name).into_lua(lua)
|
Instance::new_orphaned(class_name).into_lua(lua)
|
||||||
} else {
|
} else {
|
||||||
Err(LuaError::RuntimeError(format!(
|
Err(LuaError::RuntimeError(format!(
|
||||||
"Failed to create Instance - '{}' is not a valid class name",
|
"Failed to create Instance - '{class_name}' is not a valid class name",
|
||||||
class_name
|
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -756,7 +758,7 @@ impl LuaUserData for Instance {
|
||||||
|
|
||||||
impl Hash for Instance {
|
impl Hash for Instance {
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.dom_ref.hash(state)
|
self.dom_ref.hash(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,13 @@ impl InstanceRegistry {
|
||||||
.expect("Missing InstanceRegistry in app data")
|
.expect("Missing InstanceRegistry in app data")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Inserts a method into the instance registry.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
- If the method already exists in the registry.
|
||||||
|
*/
|
||||||
pub fn insert_method<'lua>(
|
pub fn insert_method<'lua>(
|
||||||
lua: &'lua Lua,
|
lua: &'lua Lua,
|
||||||
class_name: &str,
|
class_name: &str,
|
||||||
|
@ -80,6 +87,13 @@ impl InstanceRegistry {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Inserts a property getter into the instance registry.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
- If the property already exists in the registry.
|
||||||
|
*/
|
||||||
pub fn insert_property_getter<'lua>(
|
pub fn insert_property_getter<'lua>(
|
||||||
lua: &'lua Lua,
|
lua: &'lua Lua,
|
||||||
class_name: &str,
|
class_name: &str,
|
||||||
|
@ -109,6 +123,13 @@ impl InstanceRegistry {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Inserts a property setter into the instance registry.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
- If the property already exists in the registry.
|
||||||
|
*/
|
||||||
pub fn insert_property_setter<'lua>(
|
pub fn insert_property_setter<'lua>(
|
||||||
lua: &'lua Lua,
|
lua: &'lua Lua,
|
||||||
class_name: &str,
|
class_name: &str,
|
||||||
|
@ -138,6 +159,12 @@ impl InstanceRegistry {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Finds a method in the instance registry.
|
||||||
|
|
||||||
|
Returns `None` if the method is not found.
|
||||||
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn find_method<'lua>(
|
pub fn find_method<'lua>(
|
||||||
lua: &'lua Lua,
|
lua: &'lua Lua,
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
|
@ -159,6 +186,12 @@ impl InstanceRegistry {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Finds a property getter in the instance registry.
|
||||||
|
|
||||||
|
Returns `None` if the property getter is not found.
|
||||||
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn find_property_getter<'lua>(
|
pub fn find_property_getter<'lua>(
|
||||||
lua: &'lua Lua,
|
lua: &'lua Lua,
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
|
@ -180,6 +213,12 @@ impl InstanceRegistry {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Finds a property setter in the instance registry.
|
||||||
|
|
||||||
|
Returns `None` if the property setter is not found.
|
||||||
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn find_property_setter<'lua>(
|
pub fn find_property_setter<'lua>(
|
||||||
lua: &'lua Lua,
|
lua: &'lua Lua,
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
|
@ -202,6 +241,16 @@ impl InstanceRegistry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the class name chain for a given class name.
|
||||||
|
|
||||||
|
The chain starts with the given class name and ends with the root class.
|
||||||
|
|
||||||
|
# Panics
|
||||||
|
|
||||||
|
Panics if the class name is not valid.
|
||||||
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn class_name_chain(class_name: &str) -> Vec<&str> {
|
pub fn class_name_chain(class_name: &str) -> Vec<&str> {
|
||||||
let db = rbx_reflection_database::get();
|
let db = rbx_reflection_database::get();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use rbx_dom_weak::types::{MaterialColors, TerrainMaterials, Variant};
|
use rbx_dom_weak::types::{MaterialColors, TerrainMaterials, Variant};
|
||||||
|
|
||||||
use crate::roblox::{
|
use crate::{
|
||||||
datatypes::types::{Color3, EnumItem},
|
datatypes::types::{Color3, EnumItem},
|
||||||
shared::classes::{add_class_restricted_method, add_class_restricted_method_mut},
|
shared::classes::{add_class_restricted_method, add_class_restricted_method_mut},
|
||||||
};
|
};
|
||||||
|
@ -23,7 +23,7 @@ pub fn add_methods<'lua, M: LuaUserDataMethods<'lua, Instance>>(methods: &mut M)
|
||||||
CLASS_NAME,
|
CLASS_NAME,
|
||||||
"SetMaterialColor",
|
"SetMaterialColor",
|
||||||
terrain_set_material_color,
|
terrain_set_material_color,
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_or_create_material_colors(instance: &Instance) -> MaterialColors {
|
fn get_or_create_material_colors(instance: &Instance) -> MaterialColors {
|
|
@ -1,8 +1,6 @@
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use crate::roblox::shared::classes::{
|
use crate::shared::classes::{add_class_restricted_getter, get_or_create_property_ref_instance};
|
||||||
add_class_restricted_getter, get_or_create_property_ref_instance,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::Instance;
|
use super::Instance;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
#![allow(clippy::cargo_common_metadata)]
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use crate::lune::util::TableBuilder;
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
pub mod datatypes;
|
pub mod datatypes;
|
||||||
pub mod document;
|
pub mod document;
|
||||||
|
@ -46,6 +48,16 @@ fn create_all_exports(lua: &Lua) -> LuaResult<Vec<(&'static str, LuaValue)>> {
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a table containing all the Roblox datatypes, classes, and singletons.
|
||||||
|
|
||||||
|
Note that this is not guaranteed to contain any value unless indexed directly,
|
||||||
|
it may be optimized to use lazy initialization in the future.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
Errors when out of memory or when a value cannot be created.
|
||||||
|
*/
|
||||||
pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
|
pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
|
||||||
// FUTURE: We can probably create these lazily as users
|
// FUTURE: We can probably create these lazily as users
|
||||||
// index the main exports (this return value) table and
|
// index the main exports (this return value) table and
|
|
@ -7,7 +7,7 @@ use rbx_dom_weak::types::Variant as DomVariant;
|
||||||
use rbx_reflection::{ClassDescriptor, DataType};
|
use rbx_reflection::{ClassDescriptor, DataType};
|
||||||
|
|
||||||
use super::{property::DatabaseProperty, utils::*};
|
use super::{property::DatabaseProperty, utils::*};
|
||||||
use crate::roblox::datatypes::{
|
use crate::datatypes::{
|
||||||
conversion::DomValueToLua, types::EnumItem, userdata_impl_eq, userdata_impl_to_string,
|
conversion::DomValueToLua, types::EnumItem, userdata_impl_eq, userdata_impl_to_string,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ impl DatabaseClass {
|
||||||
/**
|
/**
|
||||||
Get the name of this class.
|
Get the name of this class.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn get_name(&self) -> String {
|
pub fn get_name(&self) -> String {
|
||||||
self.0.name.to_string()
|
self.0.name.to_string()
|
||||||
}
|
}
|
||||||
|
@ -37,6 +38,7 @@ impl DatabaseClass {
|
||||||
|
|
||||||
May be `None` if no parent class exists.
|
May be `None` if no parent class exists.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn get_superclass(&self) -> Option<String> {
|
pub fn get_superclass(&self) -> Option<String> {
|
||||||
let sup = self.0.superclass.as_ref()?;
|
let sup = self.0.superclass.as_ref()?;
|
||||||
Some(sup.to_string())
|
Some(sup.to_string())
|
||||||
|
@ -45,6 +47,7 @@ impl DatabaseClass {
|
||||||
/**
|
/**
|
||||||
Get all known properties for this class.
|
Get all known properties for this class.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn get_properties(&self) -> HashMap<String, DatabaseProperty> {
|
pub fn get_properties(&self) -> HashMap<String, DatabaseProperty> {
|
||||||
self.0
|
self.0
|
||||||
.properties
|
.properties
|
||||||
|
@ -56,6 +59,7 @@ impl DatabaseClass {
|
||||||
/**
|
/**
|
||||||
Get all default values for properties of this class.
|
Get all default values for properties of this class.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn get_defaults(&self) -> HashMap<String, DomVariant> {
|
pub fn get_defaults(&self) -> HashMap<String, DomVariant> {
|
||||||
self.0
|
self.0
|
||||||
.default_properties
|
.default_properties
|
||||||
|
@ -71,7 +75,12 @@ impl DatabaseClass {
|
||||||
to players at runtime, and top-level class categories.
|
to players at runtime, and top-level class categories.
|
||||||
*/
|
*/
|
||||||
pub fn get_tags_str(&self) -> Vec<&'static str> {
|
pub fn get_tags_str(&self) -> Vec<&'static str> {
|
||||||
self.0.tags.iter().map(class_tag_to_str).collect::<Vec<_>>()
|
self.0
|
||||||
|
.tags
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.map(class_tag_to_str)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,14 +144,12 @@ fn make_enum_value(inner: DbClass, name: impl AsRef<str>, value: u32) -> LuaResu
|
||||||
let name = name.as_ref();
|
let name = name.as_ref();
|
||||||
let enum_name = find_enum_name(inner, name).ok_or_else(|| {
|
let enum_name = find_enum_name(inner, name).ok_or_else(|| {
|
||||||
LuaError::RuntimeError(format!(
|
LuaError::RuntimeError(format!(
|
||||||
"Failed to get default property '{}' - No enum descriptor was found",
|
"Failed to get default property '{name}' - No enum descriptor was found",
|
||||||
name
|
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
EnumItem::from_enum_name_and_value(&enum_name, value).ok_or_else(|| {
|
EnumItem::from_enum_name_and_value(&enum_name, value).ok_or_else(|| {
|
||||||
LuaError::RuntimeError(format!(
|
LuaError::RuntimeError(format!(
|
||||||
"Failed to get default property '{}' - Enum.{} does not contain numeric value {}",
|
"Failed to get default property '{name}' - Enum.{enum_name} does not contain numeric value {value}",
|
||||||
name, enum_name, value
|
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
}
|
}
|
|
@ -4,7 +4,7 @@ use mlua::prelude::*;
|
||||||
|
|
||||||
use rbx_reflection::EnumDescriptor;
|
use rbx_reflection::EnumDescriptor;
|
||||||
|
|
||||||
use crate::roblox::datatypes::{userdata_impl_eq, userdata_impl_to_string};
|
use crate::datatypes::{userdata_impl_eq, userdata_impl_to_string};
|
||||||
|
|
||||||
type DbEnum = &'static EnumDescriptor<'static>;
|
type DbEnum = &'static EnumDescriptor<'static>;
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ impl DatabaseEnum {
|
||||||
/**
|
/**
|
||||||
Get the name of this enum.
|
Get the name of this enum.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn get_name(&self) -> String {
|
pub fn get_name(&self) -> String {
|
||||||
self.0.name.to_string()
|
self.0.name.to_string()
|
||||||
}
|
}
|
||||||
|
@ -31,8 +32,9 @@ impl DatabaseEnum {
|
||||||
Get all known members of this enum.
|
Get all known members of this enum.
|
||||||
|
|
||||||
Note that this is a direct map of name -> enum values,
|
Note that this is a direct map of name -> enum values,
|
||||||
and does not actually use the EnumItem datatype itself.
|
and does not actually use the `EnumItem` datatype itself.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn get_items(&self) -> HashMap<String, u32> {
|
pub fn get_items(&self) -> HashMap<String, u32> {
|
||||||
self.0
|
self.0
|
||||||
.items
|
.items
|
|
@ -4,7 +4,7 @@ use mlua::prelude::*;
|
||||||
|
|
||||||
use rbx_reflection::ReflectionDatabase;
|
use rbx_reflection::ReflectionDatabase;
|
||||||
|
|
||||||
use crate::roblox::datatypes::userdata_impl_eq;
|
use crate::datatypes::userdata_impl_eq;
|
||||||
|
|
||||||
mod class;
|
mod class;
|
||||||
mod enums;
|
mod enums;
|
||||||
|
@ -30,6 +30,7 @@ impl Database {
|
||||||
/**
|
/**
|
||||||
Creates a new database struct, referencing the bundled reflection database.
|
Creates a new database struct, referencing the bundled reflection database.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
@ -40,6 +41,7 @@ impl Database {
|
||||||
This will follow the format `x.y.z.w`, which most
|
This will follow the format `x.y.z.w`, which most
|
||||||
commonly looks something like `0.567.0.123456789`.
|
commonly looks something like `0.567.0.123456789`.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn get_version(&self) -> String {
|
pub fn get_version(&self) -> String {
|
||||||
let [x, y, z, w] = self.0.version;
|
let [x, y, z, w] = self.0.version;
|
||||||
format!("{x}.{y}.{z}.{w}")
|
format!("{x}.{y}.{z}.{w}")
|
||||||
|
@ -48,15 +50,17 @@ impl Database {
|
||||||
/**
|
/**
|
||||||
Retrieves a list of all currently known enum names.
|
Retrieves a list of all currently known enum names.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn get_enum_names(&self) -> Vec<String> {
|
pub fn get_enum_names(&self) -> Vec<String> {
|
||||||
self.0.enums.keys().map(|e| e.to_string()).collect()
|
self.0.enums.keys().map(ToString::to_string).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Retrieves a list of all currently known class names.
|
Retrieves a list of all currently known class names.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn get_class_names(&self) -> Vec<String> {
|
pub fn get_class_names(&self) -> Vec<String> {
|
||||||
self.0.classes.keys().map(|e| e.to_string()).collect()
|
self.0.classes.keys().map(ToString::to_string).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -108,14 +112,17 @@ impl Database {
|
||||||
|
|
||||||
impl LuaUserData for Database {
|
impl LuaUserData for Database {
|
||||||
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) {
|
fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) {
|
||||||
fields.add_field_method_get("Version", |_, this| Ok(this.get_version()))
|
fields.add_field_method_get("Version", |_, this| Ok(this.get_version()));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
|
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
|
||||||
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
|
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);
|
||||||
methods.add_method("GetEnumNames", |_, this, _: ()| Ok(this.get_enum_names()));
|
methods.add_method("GetEnumNames", |_, this, (): ()| Ok(this.get_enum_names()));
|
||||||
methods.add_method("GetClassNames", |_, this, _: ()| Ok(this.get_class_names()));
|
methods.add_method(
|
||||||
|
"GetClassNames",
|
||||||
|
|_, this, (): ()| Ok(this.get_class_names()),
|
||||||
|
);
|
||||||
methods.add_method("GetEnum", |_, this, name: String| Ok(this.get_enum(name)));
|
methods.add_method("GetEnum", |_, this, name: String| Ok(this.get_enum(name)));
|
||||||
methods.add_method("GetClass", |_, this, name: String| Ok(this.get_class(name)));
|
methods.add_method("GetClass", |_, this, name: String| Ok(this.get_class(name)));
|
||||||
methods.add_method("FindEnum", |_, this, name: String| Ok(this.find_enum(name)));
|
methods.add_method("FindEnum", |_, this, name: String| Ok(this.find_enum(name)));
|
|
@ -5,7 +5,7 @@ use mlua::prelude::*;
|
||||||
use rbx_reflection::{ClassDescriptor, PropertyDescriptor};
|
use rbx_reflection::{ClassDescriptor, PropertyDescriptor};
|
||||||
|
|
||||||
use super::utils::*;
|
use super::utils::*;
|
||||||
use crate::roblox::datatypes::{userdata_impl_eq, userdata_impl_to_string};
|
use crate::datatypes::{userdata_impl_eq, userdata_impl_to_string};
|
||||||
|
|
||||||
type DbClass = &'static ClassDescriptor<'static>;
|
type DbClass = &'static ClassDescriptor<'static>;
|
||||||
type DbProp = &'static PropertyDescriptor<'static>;
|
type DbProp = &'static PropertyDescriptor<'static>;
|
||||||
|
@ -25,6 +25,7 @@ impl DatabaseProperty {
|
||||||
/**
|
/**
|
||||||
Get the name of this property.
|
Get the name of this property.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn get_name(&self) -> String {
|
pub fn get_name(&self) -> String {
|
||||||
self.1.name.to_string()
|
self.1.name.to_string()
|
||||||
}
|
}
|
||||||
|
@ -36,6 +37,7 @@ impl DatabaseProperty {
|
||||||
|
|
||||||
For enums this will be a string formatted as `Enum.EnumName`.
|
For enums this will be a string formatted as `Enum.EnumName`.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn get_datatype_name(&self) -> String {
|
pub fn get_datatype_name(&self) -> String {
|
||||||
data_type_to_str(self.1.data_type.clone())
|
data_type_to_str(self.1.data_type.clone())
|
||||||
}
|
}
|
||||||
|
@ -45,8 +47,9 @@ impl DatabaseProperty {
|
||||||
|
|
||||||
All properties are writable and readable in Lune even if scriptability is not.
|
All properties are writable and readable in Lune even if scriptability is not.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn get_scriptability_str(&self) -> &'static str {
|
pub fn get_scriptability_str(&self) -> &'static str {
|
||||||
scriptability_to_str(&self.1.scriptability)
|
scriptability_to_str(self.1.scriptability)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,6 +62,7 @@ impl DatabaseProperty {
|
||||||
self.1
|
self.1
|
||||||
.tags
|
.tags
|
||||||
.iter()
|
.iter()
|
||||||
|
.copied()
|
||||||
.map(property_tag_to_str)
|
.map(property_tag_to_str)
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
use rbx_reflection::{ClassTag, DataType, PropertyTag, Scriptability};
|
use rbx_reflection::{ClassTag, DataType, PropertyTag, Scriptability};
|
||||||
|
|
||||||
use crate::roblox::datatypes::extension::DomValueExt;
|
use crate::datatypes::extension::DomValueExt;
|
||||||
|
|
||||||
pub fn data_type_to_str(data_type: DataType) -> String {
|
pub fn data_type_to_str(data_type: DataType) -> String {
|
||||||
match data_type {
|
match data_type {
|
||||||
|
@ -17,7 +17,7 @@ pub fn data_type_to_str(data_type: DataType) -> String {
|
||||||
NOTE: Remember to add any new strings here to typedefs too!
|
NOTE: Remember to add any new strings here to typedefs too!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub fn scriptability_to_str(scriptability: &Scriptability) -> &'static str {
|
pub fn scriptability_to_str(scriptability: Scriptability) -> &'static str {
|
||||||
match scriptability {
|
match scriptability {
|
||||||
Scriptability::None => "None",
|
Scriptability::None => "None",
|
||||||
Scriptability::Custom => "Custom",
|
Scriptability::Custom => "Custom",
|
||||||
|
@ -28,7 +28,7 @@ pub fn scriptability_to_str(scriptability: &Scriptability) -> &'static str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn property_tag_to_str(tag: &PropertyTag) -> &'static str {
|
pub fn property_tag_to_str(tag: PropertyTag) -> &'static str {
|
||||||
match tag {
|
match tag {
|
||||||
PropertyTag::Deprecated => "Deprecated",
|
PropertyTag::Deprecated => "Deprecated",
|
||||||
PropertyTag::Hidden => "Hidden",
|
PropertyTag::Hidden => "Hidden",
|
||||||
|
@ -41,7 +41,7 @@ pub fn property_tag_to_str(tag: &PropertyTag) -> &'static str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn class_tag_to_str(tag: &ClassTag) -> &'static str {
|
pub fn class_tag_to_str(tag: ClassTag) -> &'static str {
|
||||||
match tag {
|
match tag {
|
||||||
ClassTag::Deprecated => "Deprecated",
|
ClassTag::Deprecated => "Deprecated",
|
||||||
ClassTag::NotBrowsable => "NotBrowsable",
|
ClassTag::NotBrowsable => "NotBrowsable",
|
|
@ -2,7 +2,7 @@ use mlua::prelude::*;
|
||||||
|
|
||||||
use rbx_dom_weak::types::Variant as DomValue;
|
use rbx_dom_weak::types::Variant as DomValue;
|
||||||
|
|
||||||
use crate::roblox::instance::Instance;
|
use crate::instance::Instance;
|
||||||
|
|
||||||
use super::instance::class_is_a;
|
use super::instance::class_is_a;
|
||||||
|
|
||||||
|
@ -20,8 +20,7 @@ pub(crate) fn add_class_restricted_getter<'lua, F: LuaUserDataFields<'lua, Insta
|
||||||
field_getter(lua, this)
|
field_getter(lua, this)
|
||||||
} else {
|
} else {
|
||||||
Err(LuaError::RuntimeError(format!(
|
Err(LuaError::RuntimeError(format!(
|
||||||
"{} is not a valid member of {}",
|
"{field_name} is not a valid member of {class_name}",
|
||||||
field_name, class_name
|
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -42,8 +41,7 @@ pub(crate) fn add_class_restricted_setter<'lua, F: LuaUserDataFields<'lua, Insta
|
||||||
field_getter(lua, this, value)
|
field_getter(lua, this, value)
|
||||||
} else {
|
} else {
|
||||||
Err(LuaError::RuntimeError(format!(
|
Err(LuaError::RuntimeError(format!(
|
||||||
"{} is not a valid member of {}",
|
"{field_name} is not a valid member of {class_name}",
|
||||||
field_name, class_name
|
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -64,8 +62,7 @@ pub(crate) fn add_class_restricted_method<'lua, M: LuaUserDataMethods<'lua, Inst
|
||||||
method(lua, this, args)
|
method(lua, this, args)
|
||||||
} else {
|
} else {
|
||||||
Err(LuaError::RuntimeError(format!(
|
Err(LuaError::RuntimeError(format!(
|
||||||
"{} is not a valid member of {}",
|
"{method_name} is not a valid member of {class_name}",
|
||||||
method_name, class_name
|
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -92,8 +89,7 @@ pub(crate) fn add_class_restricted_method_mut<
|
||||||
method(lua, this, args)
|
method(lua, this, args)
|
||||||
} else {
|
} else {
|
||||||
Err(LuaError::RuntimeError(format!(
|
Err(LuaError::RuntimeError(format!(
|
||||||
"{} is not a valid member of {}",
|
"{method_name} is not a valid member of {class_name}",
|
||||||
method_name, class_name
|
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -102,7 +98,7 @@ pub(crate) fn add_class_restricted_method_mut<
|
||||||
/**
|
/**
|
||||||
Gets or creates the instance child with the given reference prop name and class name.
|
Gets or creates the instance child with the given reference prop name and class name.
|
||||||
|
|
||||||
Note that the class name here must be an exact match, it is not checked using IsA.
|
Note that the class name here must be an exact match, it is not checked using `IsA`.
|
||||||
|
|
||||||
The instance may be in one of several states but this function will guarantee that the
|
The instance may be in one of several states but this function will guarantee that the
|
||||||
property reference is correct and that the instance exists after it has been called:
|
property reference is correct and that the instance exists after it has been called:
|
|
@ -60,12 +60,12 @@ pub(crate) fn find_property_info(
|
||||||
value_type: Some(*value_type),
|
value_type: Some(*value_type),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
_ => Default::default(),
|
_ => PropertyInfo::default(),
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
} else if let Some(sup) = &class.superclass {
|
} else if let Some(sup) = &class.superclass {
|
||||||
// No property found, we should look at the superclass
|
// No property found, we should look at the superclass
|
||||||
class_name = Cow::Borrowed(sup)
|
class_name = Cow::Borrowed(sup);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ pub(crate) fn find_property_info(
|
||||||
break;
|
break;
|
||||||
} else if let Some(sup) = &class.superclass {
|
} else if let Some(sup) = &class.superclass {
|
||||||
// No default value found, we should look at the superclass
|
// No default value found, we should look at the superclass
|
||||||
class_name = Cow::Borrowed(sup)
|
class_name = Cow::Borrowed(sup);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(clippy::missing_errors_doc)]
|
||||||
|
|
||||||
use std::{any::type_name, cell::RefCell, fmt, ops};
|
use std::{any::type_name, cell::RefCell, fmt, ops};
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
@ -5,21 +7,29 @@ use mlua::prelude::*;
|
||||||
// Utility functions
|
// Utility functions
|
||||||
|
|
||||||
type ListWriter = dyn Fn(&mut fmt::Formatter<'_>, bool, &str) -> fmt::Result;
|
type ListWriter = dyn Fn(&mut fmt::Formatter<'_>, bool, &str) -> fmt::Result;
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
pub fn make_list_writer() -> Box<ListWriter> {
|
pub fn make_list_writer() -> Box<ListWriter> {
|
||||||
let first = RefCell::new(true);
|
let first = RefCell::new(true);
|
||||||
Box::new(move |f, flag, literal| {
|
Box::new(move |f, flag, literal| {
|
||||||
if flag {
|
if flag {
|
||||||
if first.take() {
|
if first.take() {
|
||||||
write!(f, "{}", literal)?;
|
write!(f, "{literal}")?;
|
||||||
} else {
|
} else {
|
||||||
write!(f, ", {}", literal)?;
|
write!(f, ", {literal}")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok::<_, fmt::Error>(())
|
Ok::<_, fmt::Error>(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Userdata metamethod implementations
|
/**
|
||||||
|
Userdata metamethod implementations
|
||||||
|
|
||||||
|
Note that many of these return [`LuaResult`] even though they don't
|
||||||
|
return any errors - this is for consistency reasons and to make it
|
||||||
|
easier to add these blanket implementations to [`LuaUserData`] impls.
|
||||||
|
*/
|
||||||
|
|
||||||
pub fn userdata_impl_to_string<D>(_: &Lua, datatype: &D, _: ()) -> LuaResult<String>
|
pub fn userdata_impl_to_string<D>(_: &Lua, datatype: &D, _: ()) -> LuaResult<String>
|
||||||
where
|
where
|
20
crates/lune-std-datetime/Cargo.toml
Normal file
20
crates/lune-std-datetime/Cargo.toml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
[package]
|
||||||
|
name = "lune-std-datetime"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
license = "MPL-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
mlua = { version = "0.9.7", features = ["luau"] }
|
||||||
|
|
||||||
|
thiserror = "1.0"
|
||||||
|
chrono = "=0.4.34" # NOTE: 0.4.35 does not compile with chrono_lc
|
||||||
|
chrono_lc = "0.1"
|
||||||
|
|
||||||
|
lune-utils = { version = "0.1.0", path = "../lune-utils" }
|
|
@ -6,31 +6,8 @@ use chrono::prelude::*;
|
||||||
use chrono::DateTime as ChronoDateTime;
|
use chrono::DateTime as ChronoDateTime;
|
||||||
use chrono_lc::LocaleDate;
|
use chrono_lc::LocaleDate;
|
||||||
|
|
||||||
use crate::lune::util::TableBuilder;
|
use crate::result::{DateTimeError, DateTimeResult};
|
||||||
|
use crate::values::DateTimeValues;
|
||||||
mod error;
|
|
||||||
mod values;
|
|
||||||
|
|
||||||
use error::*;
|
|
||||||
use values::*;
|
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<LuaTable> {
|
|
||||||
TableBuilder::new(lua)?
|
|
||||||
.with_function("fromIsoDate", |_, iso_date: String| {
|
|
||||||
Ok(DateTime::from_iso_date(iso_date)?)
|
|
||||||
})?
|
|
||||||
.with_function("fromLocalTime", |_, values| {
|
|
||||||
Ok(DateTime::from_local_time(&values)?)
|
|
||||||
})?
|
|
||||||
.with_function("fromUniversalTime", |_, values| {
|
|
||||||
Ok(DateTime::from_universal_time(&values)?)
|
|
||||||
})?
|
|
||||||
.with_function("fromUnixTimestamp", |_, timestamp| {
|
|
||||||
Ok(DateTime::from_unix_timestamp_float(timestamp)?)
|
|
||||||
})?
|
|
||||||
.with_function("now", |_, ()| Ok(DateTime::now()))?
|
|
||||||
.build_readonly()
|
|
||||||
}
|
|
||||||
|
|
||||||
const DEFAULT_FORMAT: &str = "%Y-%m-%d %H:%M:%S";
|
const DEFAULT_FORMAT: &str = "%Y-%m-%d %H:%M:%S";
|
||||||
const DEFAULT_LOCALE: &str = "en";
|
const DEFAULT_LOCALE: &str = "en";
|
||||||
|
@ -49,6 +26,7 @@ impl DateTime {
|
||||||
|
|
||||||
See [`chrono::DateTime::now`] for additional details.
|
See [`chrono::DateTime::now`] for additional details.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn now() -> Self {
|
pub fn now() -> Self {
|
||||||
Self { inner: Utc::now() }
|
Self { inner: Utc::now() }
|
||||||
}
|
}
|
||||||
|
@ -66,6 +44,10 @@ impl DateTime {
|
||||||
```
|
```
|
||||||
|
|
||||||
See [`chrono::DateTime::from_timestamp`] for additional details.
|
See [`chrono::DateTime::from_timestamp`] for additional details.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
Returns an error if the input value is out of range.
|
||||||
*/
|
*/
|
||||||
pub fn from_unix_timestamp_float(unix_timestamp: f64) -> DateTimeResult<Self> {
|
pub fn from_unix_timestamp_float(unix_timestamp: f64) -> DateTimeResult<Self> {
|
||||||
let whole = unix_timestamp.trunc() as i64;
|
let whole = unix_timestamp.trunc() as i64;
|
||||||
|
@ -84,6 +66,10 @@ impl DateTime {
|
||||||
|
|
||||||
See [`chrono::NaiveDate::from_ymd_opt`] and [`chrono::NaiveTime::from_hms_milli_opt`]
|
See [`chrono::NaiveDate::from_ymd_opt`] and [`chrono::NaiveTime::from_hms_milli_opt`]
|
||||||
for additional details and cases where this constructor may return an error.
|
for additional details and cases where this constructor may return an error.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
Returns an error if the date or time values are invalid.
|
||||||
*/
|
*/
|
||||||
pub fn from_universal_time(values: &DateTimeValues) -> DateTimeResult<Self> {
|
pub fn from_universal_time(values: &DateTimeValues) -> DateTimeResult<Self> {
|
||||||
let date = NaiveDate::from_ymd_opt(values.year, values.month, values.day)
|
let date = NaiveDate::from_ymd_opt(values.year, values.month, values.day)
|
||||||
|
@ -108,6 +94,10 @@ impl DateTime {
|
||||||
|
|
||||||
See [`chrono::NaiveDate::from_ymd_opt`] and [`chrono::NaiveTime::from_hms_milli_opt`]
|
See [`chrono::NaiveDate::from_ymd_opt`] and [`chrono::NaiveTime::from_hms_milli_opt`]
|
||||||
for additional details and cases where this constructor may return an error.
|
for additional details and cases where this constructor may return an error.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
Returns an error if the date or time values are invalid or ambiguous.
|
||||||
*/
|
*/
|
||||||
pub fn from_local_time(values: &DateTimeValues) -> DateTimeResult<Self> {
|
pub fn from_local_time(values: &DateTimeValues) -> DateTimeResult<Self> {
|
||||||
let date = NaiveDate::from_ymd_opt(values.year, values.month, values.day)
|
let date = NaiveDate::from_ymd_opt(values.year, values.month, values.day)
|
||||||
|
@ -138,6 +128,7 @@ impl DateTime {
|
||||||
|
|
||||||
See [`chrono_lc::DateTime::formatl`] for additional details.
|
See [`chrono_lc::DateTime::formatl`] for additional details.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn format_string_local(&self, format: Option<&str>, locale: Option<&str>) -> String {
|
pub fn format_string_local(&self, format: Option<&str>, locale: Option<&str>) -> String {
|
||||||
self.inner
|
self.inner
|
||||||
.with_timezone(&Local)
|
.with_timezone(&Local)
|
||||||
|
@ -156,6 +147,7 @@ impl DateTime {
|
||||||
|
|
||||||
See [`chrono_lc::DateTime::formatl`] for additional details.
|
See [`chrono_lc::DateTime::formatl`] for additional details.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn format_string_universal(&self, format: Option<&str>, locale: Option<&str>) -> String {
|
pub fn format_string_universal(&self, format: Option<&str>, locale: Option<&str>) -> String {
|
||||||
self.inner
|
self.inner
|
||||||
.with_timezone(&Utc)
|
.with_timezone(&Utc)
|
||||||
|
@ -171,6 +163,10 @@ impl DateTime {
|
||||||
`1996-12-19T16:39:57-08:00`, into a new `DateTime` struct.
|
`1996-12-19T16:39:57-08:00`, into a new `DateTime` struct.
|
||||||
|
|
||||||
See [`chrono::DateTime::parse_from_rfc3339`] for additional details.
|
See [`chrono::DateTime::parse_from_rfc3339`] for additional details.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
Returns an error if the input string is not a valid RFC 3339 date-time.
|
||||||
*/
|
*/
|
||||||
pub fn from_iso_date(iso_date: impl AsRef<str>) -> DateTimeResult<Self> {
|
pub fn from_iso_date(iso_date: impl AsRef<str>) -> DateTimeResult<Self> {
|
||||||
let inner = ChronoDateTime::parse_from_rfc3339(iso_date.as_ref())?.with_timezone(&Utc);
|
let inner = ChronoDateTime::parse_from_rfc3339(iso_date.as_ref())?.with_timezone(&Utc);
|
||||||
|
@ -181,6 +177,7 @@ impl DateTime {
|
||||||
Extracts individual date & time values from this
|
Extracts individual date & time values from this
|
||||||
`DateTime`, using the current local time zone.
|
`DateTime`, using the current local time zone.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn to_local_time(self) -> DateTimeValues {
|
pub fn to_local_time(self) -> DateTimeValues {
|
||||||
DateTimeValues::from(self.inner.with_timezone(&Local))
|
DateTimeValues::from(self.inner.with_timezone(&Local))
|
||||||
}
|
}
|
||||||
|
@ -189,6 +186,7 @@ impl DateTime {
|
||||||
Extracts individual date & time values from this
|
Extracts individual date & time values from this
|
||||||
`DateTime`, using the universal (UTC) time zone.
|
`DateTime`, using the universal (UTC) time zone.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn to_universal_time(self) -> DateTimeValues {
|
pub fn to_universal_time(self) -> DateTimeValues {
|
||||||
DateTimeValues::from(self.inner.with_timezone(&Utc))
|
DateTimeValues::from(self.inner.with_timezone(&Utc))
|
||||||
}
|
}
|
||||||
|
@ -198,6 +196,7 @@ impl DateTime {
|
||||||
|
|
||||||
See [`chrono::DateTime::to_rfc3339`] for additional details.
|
See [`chrono::DateTime::to_rfc3339`] for additional details.
|
||||||
*/
|
*/
|
||||||
|
#[must_use]
|
||||||
pub fn to_iso_date(self) -> String {
|
pub fn to_iso_date(self) -> String {
|
||||||
self.inner.to_rfc3339()
|
self.inner.to_rfc3339()
|
||||||
}
|
}
|
36
crates/lune-std-datetime/src/lib.rs
Normal file
36
crates/lune-std-datetime/src/lib.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#![allow(clippy::cargo_common_metadata)]
|
||||||
|
|
||||||
|
use mlua::prelude::*;
|
||||||
|
|
||||||
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
mod date_time;
|
||||||
|
mod result;
|
||||||
|
mod values;
|
||||||
|
|
||||||
|
pub use self::date_time::DateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates the `datetime` standard library module.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
Errors when out of memory.
|
||||||
|
*/
|
||||||
|
pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
|
||||||
|
TableBuilder::new(lua)?
|
||||||
|
.with_function("fromIsoDate", |_, iso_date: String| {
|
||||||
|
Ok(DateTime::from_iso_date(iso_date)?)
|
||||||
|
})?
|
||||||
|
.with_function("fromLocalTime", |_, values| {
|
||||||
|
Ok(DateTime::from_local_time(&values)?)
|
||||||
|
})?
|
||||||
|
.with_function("fromUniversalTime", |_, values| {
|
||||||
|
Ok(DateTime::from_universal_time(&values)?)
|
||||||
|
})?
|
||||||
|
.with_function("fromUnixTimestamp", |_, timestamp| {
|
||||||
|
Ok(DateTime::from_unix_timestamp_float(timestamp)?)
|
||||||
|
})?
|
||||||
|
.with_function("now", |_, ()| Ok(DateTime::now()))?
|
||||||
|
.build_readonly()
|
||||||
|
}
|
|
@ -2,9 +2,9 @@ use mlua::prelude::*;
|
||||||
|
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
|
|
||||||
use crate::lune::util::TableBuilder;
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
use super::error::{DateTimeError, DateTimeResult};
|
use super::result::{DateTimeError, DateTimeResult};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct DateTimeValues {
|
pub struct DateTimeValues {
|
||||||
|
@ -61,9 +61,9 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Conversion methods between DateTimeValues and plain lua tables
|
Conversion methods between `DateTimeValues` and plain lua tables
|
||||||
|
|
||||||
Note that the IntoLua implementation here uses a read-only table,
|
Note that the `IntoLua` implementation here uses a read-only table,
|
||||||
since we generally want to convert into lua when we know we have
|
since we generally want to convert into lua when we know we have
|
||||||
a fixed point in time, and we guarantee that it doesn't change
|
a fixed point in time, and we guarantee that it doesn't change
|
||||||
*/
|
*/
|
||||||
|
@ -118,8 +118,8 @@ impl IntoLua<'_> for DateTimeValues {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Conversion methods between chrono's timezone-aware DateTime to
|
Conversion methods between chrono's timezone-aware `DateTime` to
|
||||||
and from our non-timezone-aware DateTimeValues values struct
|
and from our non-timezone-aware `DateTimeValues` values struct
|
||||||
*/
|
*/
|
||||||
|
|
||||||
impl<T: TimeZone> From<DateTime<T>> for DateTimeValues {
|
impl<T: TimeZone> From<DateTime<T>> for DateTimeValues {
|
21
crates/lune-std-fs/Cargo.toml
Normal file
21
crates/lune-std-fs/Cargo.toml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
[package]
|
||||||
|
name = "lune-std-fs"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
license = "MPL-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
mlua = { version = "0.9.7", features = ["luau"] }
|
||||||
|
|
||||||
|
bstr = "1.9"
|
||||||
|
|
||||||
|
tokio = { version = "1", default-features = false, features = ["fs"] }
|
||||||
|
|
||||||
|
lune-utils = { version = "0.1.0", path = "../lune-utils" }
|
||||||
|
lune-std-datetime = { version = "0.1.0", path = "../lune-std-datetime" }
|
|
@ -13,7 +13,7 @@ pub struct CopyContents {
|
||||||
pub files: Vec<(usize, PathBuf)>,
|
pub files: Vec<(usize, PathBuf)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_contents_at(root: PathBuf, _options: FsWriteOptions) -> LuaResult<CopyContents> {
|
async fn get_contents_at(root: PathBuf, _: FsWriteOptions) -> LuaResult<CopyContents> {
|
||||||
let mut dirs = Vec::new();
|
let mut dirs = Vec::new();
|
||||||
let mut files = Vec::new();
|
let mut files = Vec::new();
|
||||||
|
|
||||||
|
@ -53,11 +53,11 @@ async fn get_contents_at(root: PathBuf, _options: FsWriteOptions) -> LuaResult<C
|
||||||
|
|
||||||
// Ensure that all directory and file paths are relative to the root path
|
// Ensure that all directory and file paths are relative to the root path
|
||||||
// SAFETY: Since we only ever push dirs and files relative to the root, unwrap is safe
|
// SAFETY: Since we only ever push dirs and files relative to the root, unwrap is safe
|
||||||
for (_, dir) in dirs.iter_mut() {
|
for (_, dir) in &mut dirs {
|
||||||
*dir = dir.strip_prefix(&normalized_root).unwrap().to_path_buf()
|
*dir = dir.strip_prefix(&normalized_root).unwrap().to_path_buf();
|
||||||
}
|
}
|
||||||
for (_, file) in files.iter_mut() {
|
for (_, file) in &mut files {
|
||||||
*file = file.strip_prefix(&normalized_root).unwrap().to_path_buf()
|
*file = file.strip_prefix(&normalized_root).unwrap().to_path_buf();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUTURE: Deduplicate paths such that these directories:
|
// FUTURE: Deduplicate paths such that these directories:
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(clippy::cargo_common_metadata)]
|
||||||
|
|
||||||
use std::io::ErrorKind as IoErrorKind;
|
use std::io::ErrorKind as IoErrorKind;
|
||||||
use std::path::{PathBuf, MAIN_SEPARATOR};
|
use std::path::{PathBuf, MAIN_SEPARATOR};
|
||||||
|
|
||||||
|
@ -5,17 +7,24 @@ use bstr::{BString, ByteSlice};
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
|
|
||||||
use crate::lune::util::TableBuilder;
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
mod copy;
|
mod copy;
|
||||||
mod metadata;
|
mod metadata;
|
||||||
mod options;
|
mod options;
|
||||||
|
|
||||||
use copy::copy;
|
use self::copy::copy;
|
||||||
use metadata::FsMetadata;
|
use self::metadata::FsMetadata;
|
||||||
use options::FsWriteOptions;
|
use self::options::FsWriteOptions;
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<LuaTable> {
|
/**
|
||||||
|
Creates the `fs` standard library module.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
Errors when out of memory.
|
||||||
|
*/
|
||||||
|
pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
|
||||||
TableBuilder::new(lua)?
|
TableBuilder::new(lua)?
|
||||||
.with_async_function("readFile", fs_read_file)?
|
.with_async_function("readFile", fs_read_file)?
|
||||||
.with_async_function("readDir", fs_read_dir)?
|
.with_async_function("readDir", fs_read_dir)?
|
|
@ -8,7 +8,7 @@ use std::{
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use crate::lune::builtins::datetime::DateTime;
|
use lune_std_datetime::DateTime;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum FsMetadataKind {
|
pub enum FsMetadataKind {
|
16
crates/lune-std-luau/Cargo.toml
Normal file
16
crates/lune-std-luau/Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "lune-std-luau"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
license = "MPL-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
mlua = { version = "0.9.7", features = ["luau"] }
|
||||||
|
|
||||||
|
lune-utils = { version = "0.1.0", path = "../lune-utils" }
|
|
@ -1,13 +1,23 @@
|
||||||
|
#![allow(clippy::cargo_common_metadata)]
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use crate::lune::util::TableBuilder;
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
mod options;
|
mod options;
|
||||||
use options::{LuauCompileOptions, LuauLoadOptions};
|
|
||||||
|
use self::options::{LuauCompileOptions, LuauLoadOptions};
|
||||||
|
|
||||||
const BYTECODE_ERROR_BYTE: u8 = 0;
|
const BYTECODE_ERROR_BYTE: u8 = 0;
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<LuaTable> {
|
/**
|
||||||
|
Creates the `luau` standard library module.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
Errors when out of memory.
|
||||||
|
*/
|
||||||
|
pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
|
||||||
TableBuilder::new(lua)?
|
TableBuilder::new(lua)?
|
||||||
.with_function("compile", compile_source)?
|
.with_function("compile", compile_source)?
|
||||||
.with_function("load", load_source)?
|
.with_function("load", load_source)?
|
|
@ -1,8 +1,14 @@
|
||||||
|
#![allow(clippy::struct_field_names)]
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use mlua::Compiler as LuaCompiler;
|
use mlua::Compiler as LuaCompiler;
|
||||||
|
|
||||||
const DEFAULT_DEBUG_NAME: &str = "luau.load(...)";
|
const DEFAULT_DEBUG_NAME: &str = "luau.load(...)";
|
||||||
|
|
||||||
|
/**
|
||||||
|
Options for compiling Lua source code.
|
||||||
|
*/
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct LuauCompileOptions {
|
pub struct LuauCompileOptions {
|
||||||
pub(crate) optimization_level: u8,
|
pub(crate) optimization_level: u8,
|
||||||
pub(crate) coverage_level: u8,
|
pub(crate) coverage_level: u8,
|
||||||
|
@ -73,6 +79,10 @@ impl<'lua> FromLua<'lua> for LuauCompileOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Options for loading Lua source code.
|
||||||
|
*/
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub struct LuauLoadOptions<'lua> {
|
pub struct LuauLoadOptions<'lua> {
|
||||||
pub(crate) debug_name: String,
|
pub(crate) debug_name: String,
|
||||||
pub(crate) environment: Option<LuaTable<'lua>>,
|
pub(crate) environment: Option<LuaTable<'lua>>,
|
37
crates/lune-std-net/Cargo.toml
Normal file
37
crates/lune-std-net/Cargo.toml
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[package]
|
||||||
|
name = "lune-std-net"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
license = "MPL-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
mlua = { version = "0.9.7", features = ["luau"] }
|
||||||
|
mlua-luau-scheduler = "0.0.2"
|
||||||
|
|
||||||
|
bstr = "1.9"
|
||||||
|
futures-util = "0.3"
|
||||||
|
hyper = { version = "1.1", features = ["full"] }
|
||||||
|
hyper-util = { version = "0.1", features = ["full"] }
|
||||||
|
http = "1.0"
|
||||||
|
http-body-util = { version = "0.1" }
|
||||||
|
hyper-tungstenite = { version = "0.13" }
|
||||||
|
reqwest = { version = "0.11", default-features = false, features = [
|
||||||
|
"rustls-tls",
|
||||||
|
] }
|
||||||
|
tokio-tungstenite = { version = "0.21", features = ["rustls-tls-webpki-roots"] }
|
||||||
|
urlencoding = "2.1"
|
||||||
|
|
||||||
|
tokio = { version = "1", default-features = false, features = [
|
||||||
|
"sync",
|
||||||
|
"net",
|
||||||
|
"macros",
|
||||||
|
] }
|
||||||
|
|
||||||
|
lune-utils = { version = "0.1.0", path = "../lune-utils" }
|
||||||
|
lune-std-serde = { version = "0.1.0", path = "../lune-std-serde" }
|
|
@ -4,10 +4,8 @@ use mlua::prelude::*;
|
||||||
|
|
||||||
use reqwest::header::{HeaderMap, HeaderName, HeaderValue, CONTENT_ENCODING};
|
use reqwest::header::{HeaderMap, HeaderName, HeaderValue, CONTENT_ENCODING};
|
||||||
|
|
||||||
use crate::lune::{
|
use lune_std_serde::{decompress, CompressDecompressFormat};
|
||||||
builtins::serde::compress_decompress::{decompress, CompressDecompressFormat},
|
use lune_utils::TableBuilder;
|
||||||
util::TableBuilder,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{config::RequestConfig, util::header_map_to_table};
|
use super::{config::RequestConfig, util::header_map_to_table};
|
||||||
|
|
||||||
|
@ -103,7 +101,7 @@ impl NetClient {
|
||||||
.and_then(|(_, value)| value.to_str().ok())
|
.and_then(|(_, value)| value.to_str().ok())
|
||||||
.and_then(CompressDecompressFormat::detect_from_header_str);
|
.and_then(CompressDecompressFormat::detect_from_header_str);
|
||||||
if let Some(format) = decompress_format {
|
if let Some(format) = decompress_format {
|
||||||
res_bytes = decompress(format, res_bytes).await?;
|
res_bytes = decompress(res_bytes, format).await?;
|
||||||
res_decompressed = true;
|
res_decompressed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -83,7 +83,7 @@ impl FromLua<'_> for RequestConfig {
|
||||||
query: HashMap::new(),
|
query: HashMap::new(),
|
||||||
headers: HashMap::new(),
|
headers: HashMap::new(),
|
||||||
body: None,
|
body: None,
|
||||||
options: Default::default(),
|
options: RequestConfigOptions::default(),
|
||||||
})
|
})
|
||||||
} else if let LuaValue::Table(tab) = value {
|
} else if let LuaValue::Table(tab) = value {
|
||||||
// If we got a table we are able to configure the entire request
|
// If we got a table we are able to configure the entire request
|
|
@ -1,4 +1,4 @@
|
||||||
#![allow(unused_variables)]
|
#![allow(clippy::cargo_common_metadata)]
|
||||||
|
|
||||||
use bstr::BString;
|
use bstr::BString;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
@ -10,7 +10,7 @@ mod server;
|
||||||
mod util;
|
mod util;
|
||||||
mod websocket;
|
mod websocket;
|
||||||
|
|
||||||
use crate::lune::util::TableBuilder;
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
use self::{
|
use self::{
|
||||||
client::{NetClient, NetClientBuilder},
|
client::{NetClient, NetClientBuilder},
|
||||||
|
@ -20,9 +20,16 @@ use self::{
|
||||||
websocket::NetWebSocket,
|
websocket::NetWebSocket,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::serde::encode_decode::{EncodeDecodeConfig, EncodeDecodeFormat};
|
use lune_std_serde::{decode, encode, EncodeDecodeConfig, EncodeDecodeFormat};
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<LuaTable> {
|
/**
|
||||||
|
Creates the `net` standard library module.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
Errors when out of memory.
|
||||||
|
*/
|
||||||
|
pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
|
||||||
NetClientBuilder::new()
|
NetClientBuilder::new()
|
||||||
.headers(&[("User-Agent", create_user_agent_header(lua)?)])?
|
.headers(&[("User-Agent", create_user_agent_header(lua)?)])?
|
||||||
.build()?
|
.build()?
|
||||||
|
@ -42,12 +49,13 @@ fn net_json_encode<'lua>(
|
||||||
lua: &'lua Lua,
|
lua: &'lua Lua,
|
||||||
(val, pretty): (LuaValue<'lua>, Option<bool>),
|
(val, pretty): (LuaValue<'lua>, Option<bool>),
|
||||||
) -> LuaResult<LuaString<'lua>> {
|
) -> LuaResult<LuaString<'lua>> {
|
||||||
EncodeDecodeConfig::from((EncodeDecodeFormat::Json, pretty.unwrap_or_default()))
|
let config = EncodeDecodeConfig::from((EncodeDecodeFormat::Json, pretty.unwrap_or_default()));
|
||||||
.serialize_to_string(lua, val)
|
encode(val, lua, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn net_json_decode(lua: &Lua, json: BString) -> LuaResult<LuaValue> {
|
fn net_json_decode(lua: &Lua, json: BString) -> LuaResult<LuaValue> {
|
||||||
EncodeDecodeConfig::from(EncodeDecodeFormat::Json).deserialize_from_string(lua, json)
|
let config = EncodeDecodeConfig::from(EncodeDecodeFormat::Json);
|
||||||
|
decode(json, lua, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn net_request(lua: &Lua, config: RequestConfig) -> LuaResult<LuaTable> {
|
async fn net_request(lua: &Lua, config: RequestConfig) -> LuaResult<LuaTable> {
|
|
@ -10,7 +10,7 @@ use tokio::{net::TcpListener, pin};
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use mlua_luau_scheduler::LuaSpawnExt;
|
use mlua_luau_scheduler::LuaSpawnExt;
|
||||||
|
|
||||||
use crate::lune::util::TableBuilder;
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
use super::config::ServeConfig;
|
use super::config::ServeConfig;
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ pub async fn serve<'lua>(
|
||||||
|
|
||||||
// Wait for either a new connection or a shutdown signal
|
// Wait for either a new connection or a shutdown signal
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = fut_accept => {}
|
() = fut_accept => {}
|
||||||
res = fut_shutdown => {
|
res = fut_shutdown => {
|
||||||
// NOTE: We will only get a RecvError here if the serve handle is dropped,
|
// NOTE: We will only get a RecvError here if the serve handle is dropped,
|
||||||
// this means lua has garbage collected it and the user does not want
|
// this means lua has garbage collected it and the user does not want
|
||||||
|
@ -97,8 +97,8 @@ pub async fn serve<'lua>(
|
||||||
TableBuilder::new(lua)?
|
TableBuilder::new(lua)?
|
||||||
.with_value("ip", addr.ip().to_string())?
|
.with_value("ip", addr.ip().to_string())?
|
||||||
.with_value("port", addr.port())?
|
.with_value("port", addr.port())?
|
||||||
.with_function("stop", move |lua, _: ()| match shutdown_tx.send(true) {
|
.with_function("stop", move |_, (): ()| match shutdown_tx.send(true) {
|
||||||
Ok(_) => Ok(()),
|
Ok(()) => Ok(()),
|
||||||
Err(_) => Err(LuaError::runtime("Server already stopped")),
|
Err(_) => Err(LuaError::runtime("Server already stopped")),
|
||||||
})?
|
})?
|
||||||
.build_readonly()
|
.build_readonly()
|
|
@ -4,7 +4,7 @@ use http::request::Parts;
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use crate::lune::util::TableBuilder;
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
pub(super) struct LuaRequest {
|
pub(super) struct LuaRequest {
|
||||||
pub(super) _remote_addr: SocketAddr,
|
pub(super) _remote_addr: SocketAddr,
|
|
@ -5,7 +5,7 @@ use reqwest::header::HeaderMap;
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use crate::lune::util::TableBuilder;
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
pub fn create_user_agent_header(lua: &Lua) -> LuaResult<String> {
|
pub fn create_user_agent_header(lua: &Lua) -> LuaResult<String> {
|
||||||
let version_global = lua
|
let version_global = lua
|
||||||
|
@ -28,7 +28,7 @@ pub fn header_map_to_table(
|
||||||
remove_content_headers: bool,
|
remove_content_headers: bool,
|
||||||
) -> LuaResult<LuaTable> {
|
) -> LuaResult<LuaTable> {
|
||||||
let mut res_headers: HashMap<String, Vec<String>> = HashMap::new();
|
let mut res_headers: HashMap<String, Vec<String>> = HashMap::new();
|
||||||
for (name, value) in headers.iter() {
|
for (name, value) in &headers {
|
||||||
let name = name.as_str();
|
let name = name.as_str();
|
||||||
let value = value.to_str().unwrap().to_owned();
|
let value = value.to_str().unwrap().to_owned();
|
||||||
if let Some(existing) = res_headers.get_mut(name) {
|
if let Some(existing) = res_headers.get_mut(name) {
|
|
@ -23,7 +23,7 @@ use hyper_tungstenite::{
|
||||||
WebSocketStream,
|
WebSocketStream,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::lune::util::TableBuilder;
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
// Wrapper implementation for compatibility and changing colon syntax to dot syntax
|
// Wrapper implementation for compatibility and changing colon syntax to dot syntax
|
||||||
const WEB_SOCKET_IMPL_LUA: &str = r#"
|
const WEB_SOCKET_IMPL_LUA: &str = r#"
|
||||||
|
@ -155,7 +155,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
methods.add_async_method("close", |lua, this, code: Option<u16>| async move {
|
methods.add_async_method("close", |_, this, code: Option<u16>| async move {
|
||||||
this.close(code).await
|
this.close(code).await
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ where
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
methods.add_async_method("next", |lua, this, _: ()| async move {
|
methods.add_async_method("next", |lua, this, (): ()| async move {
|
||||||
let msg = this.next().await?;
|
let msg = this.next().await?;
|
||||||
|
|
||||||
if let Some(WsMessage::Close(Some(frame))) = msg.as_ref() {
|
if let Some(WsMessage::Close(Some(frame))) = msg.as_ref() {
|
26
crates/lune-std-process/Cargo.toml
Normal file
26
crates/lune-std-process/Cargo.toml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
[package]
|
||||||
|
name = "lune-std-process"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
license = "MPL-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
mlua = { version = "0.9.7", features = ["luau"] }
|
||||||
|
mlua-luau-scheduler = "0.0.2"
|
||||||
|
|
||||||
|
directories = "5.0"
|
||||||
|
pin-project = "1.0"
|
||||||
|
os_str_bytes = { version = "7.0", features = ["conversions"] }
|
||||||
|
|
||||||
|
tokio = { version = "1", default-features = false, features = [
|
||||||
|
"sync",
|
||||||
|
"process",
|
||||||
|
] }
|
||||||
|
|
||||||
|
lune-utils = { version = "0.1.0", path = "../lune-utils" }
|
|
@ -1,36 +1,49 @@
|
||||||
|
#![allow(clippy::cargo_common_metadata)]
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
env::{self, consts},
|
env::{
|
||||||
path,
|
self,
|
||||||
|
consts::{ARCH, OS},
|
||||||
|
},
|
||||||
|
path::MAIN_SEPARATOR,
|
||||||
process::Stdio,
|
process::Stdio,
|
||||||
};
|
};
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
|
use lune_utils::TableBuilder;
|
||||||
use mlua_luau_scheduler::{Functions, LuaSpawnExt};
|
use mlua_luau_scheduler::{Functions, LuaSpawnExt};
|
||||||
use os_str_bytes::RawOsString;
|
use os_str_bytes::RawOsString;
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
|
|
||||||
use crate::lune::util::{paths::CWD, TableBuilder};
|
|
||||||
|
|
||||||
mod tee_writer;
|
|
||||||
|
|
||||||
mod options;
|
mod options;
|
||||||
use options::ProcessSpawnOptions;
|
mod tee_writer;
|
||||||
|
|
||||||
mod wait_for_child;
|
mod wait_for_child;
|
||||||
use wait_for_child::{wait_for_child, WaitForChildResult};
|
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<LuaTable> {
|
use self::options::ProcessSpawnOptions;
|
||||||
let cwd_str = {
|
use self::wait_for_child::{wait_for_child, WaitForChildResult};
|
||||||
let cwd_str = CWD.to_string_lossy().to_string();
|
|
||||||
if !cwd_str.ends_with(path::MAIN_SEPARATOR) {
|
use lune_utils::path::get_current_dir;
|
||||||
format!("{cwd_str}{}", path::MAIN_SEPARATOR)
|
|
||||||
} else {
|
/**
|
||||||
cwd_str
|
Creates the `process` standard library module.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
Errors when out of memory.
|
||||||
|
*/
|
||||||
|
#[allow(clippy::missing_panics_doc)]
|
||||||
|
pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
|
||||||
|
let mut cwd_str = get_current_dir()
|
||||||
|
.to_str()
|
||||||
|
.expect("cwd should be valid UTF-8")
|
||||||
|
.to_string();
|
||||||
|
if !cwd_str.ends_with(MAIN_SEPARATOR) {
|
||||||
|
cwd_str.push(MAIN_SEPARATOR);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
// Create constants for OS & processor architecture
|
// Create constants for OS & processor architecture
|
||||||
let os = lua.create_string(&consts::OS.to_lowercase())?;
|
let os = lua.create_string(&OS.to_lowercase())?;
|
||||||
let arch = lua.create_string(&consts::ARCH.to_lowercase())?;
|
let arch = lua.create_string(&ARCH.to_lowercase())?;
|
||||||
// Create readonly args array
|
// Create readonly args array
|
||||||
let args_vec = lua
|
let args_vec = lua
|
||||||
.app_data_ref::<Vec<String>>()
|
.app_data_ref::<Vec<String>>()
|
||||||
|
@ -94,9 +107,7 @@ fn process_env_set<'lua>(
|
||||||
Err(LuaError::RuntimeError(
|
Err(LuaError::RuntimeError(
|
||||||
"Key must not contain the NUL character".to_string(),
|
"Key must not contain the NUL character".to_string(),
|
||||||
))
|
))
|
||||||
} else {
|
} else if let Some(value) = value {
|
||||||
match value {
|
|
||||||
Some(value) => {
|
|
||||||
// Make sure value is valid, otherwise set_var will panic
|
// Make sure value is valid, otherwise set_var will panic
|
||||||
if value.contains('\0') {
|
if value.contains('\0') {
|
||||||
Err(LuaError::RuntimeError(
|
Err(LuaError::RuntimeError(
|
||||||
|
@ -106,21 +117,18 @@ fn process_env_set<'lua>(
|
||||||
env::set_var(&key, &value);
|
env::set_var(&key, &value);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
None => {
|
|
||||||
env::remove_var(&key);
|
env::remove_var(&key);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_env_iter<'lua>(
|
fn process_env_iter<'lua>(
|
||||||
lua: &'lua Lua,
|
lua: &'lua Lua,
|
||||||
(_, _): (LuaValue<'lua>, ()),
|
(_, ()): (LuaValue<'lua>, ()),
|
||||||
) -> LuaResult<LuaFunction<'lua>> {
|
) -> LuaResult<LuaFunction<'lua>> {
|
||||||
let mut vars = env::vars_os().collect::<Vec<_>>().into_iter();
|
let mut vars = env::vars_os().collect::<Vec<_>>().into_iter();
|
||||||
lua.create_function_mut(move |lua, _: ()| match vars.next() {
|
lua.create_function_mut(move |lua, (): ()| match vars.next() {
|
||||||
Some((key, value)) => {
|
Some((key, value)) => {
|
||||||
let raw_key = RawOsString::new(key);
|
let raw_key = RawOsString::new(key);
|
||||||
let raw_value = RawOsString::new(value);
|
let raw_value = RawOsString::new(value);
|
||||||
|
@ -149,10 +157,10 @@ async fn process_spawn(
|
||||||
An exit code may be missing if the process was terminated by
|
An exit code may be missing if the process was terminated by
|
||||||
some external signal, which is the only time we use this default
|
some external signal, which is the only time we use this default
|
||||||
*/
|
*/
|
||||||
let code = res.status.code().unwrap_or(match res.stderr.is_empty() {
|
let code = res
|
||||||
true => 0,
|
.status
|
||||||
false => 1,
|
.code()
|
||||||
});
|
.unwrap_or(i32::from(!res.stderr.is_empty()));
|
||||||
|
|
||||||
// Construct and return a readonly lua table with results
|
// Construct and return a readonly lua table with results
|
||||||
TableBuilder::new(lua)?
|
TableBuilder::new(lua)?
|
||||||
|
@ -174,9 +182,10 @@ async fn spawn_command(
|
||||||
|
|
||||||
let mut child = options
|
let mut child = options
|
||||||
.into_command(program, args)
|
.into_command(program, args)
|
||||||
.stdin(match stdin.is_some() {
|
.stdin(if stdin.is_some() {
|
||||||
true => Stdio::piped(),
|
Stdio::piped()
|
||||||
false => Stdio::null(),
|
} else {
|
||||||
|
Stdio::null()
|
||||||
})
|
})
|
||||||
.stdout(stdout.as_stdio())
|
.stdout(stdout.as_stdio())
|
||||||
.stderr(stderr.as_stdio())
|
.stderr(stderr.as_stdio())
|
|
@ -1,6 +1,5 @@
|
||||||
use std::{fmt, process::Stdio, str::FromStr};
|
use std::{fmt, process::Stdio, str::FromStr};
|
||||||
|
|
||||||
use itertools::Itertools;
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
||||||
|
@ -55,6 +54,7 @@ impl FromStr for ProcessSpawnOptionsStdioKind {
|
||||||
ProcessSpawnOptionsStdioKind::all()
|
ProcessSpawnOptionsStdioKind::all()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|k| format!("'{k}'"))
|
.map(|k| format!("'{k}'"))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
.join(", ")
|
.join(", ")
|
||||||
)))
|
)))
|
||||||
}
|
}
|
|
@ -56,7 +56,7 @@ impl<'lua> FromLua<'lua> for ProcessSpawnOptions {
|
||||||
"Invalid value for option 'cwd' - failed to get home directory",
|
"Invalid value for option 'cwd' - failed to get home directory",
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
cwd = user_dirs.home_dir().join(stripped)
|
cwd = user_dirs.home_dir().join(stripped);
|
||||||
}
|
}
|
||||||
if !cwd.exists() {
|
if !cwd.exists() {
|
||||||
return Err(LuaError::runtime(
|
return Err(LuaError::runtime(
|
|
@ -24,8 +24,7 @@ where
|
||||||
R: AsyncRead + Unpin,
|
R: AsyncRead + Unpin,
|
||||||
{
|
{
|
||||||
Ok(match kind {
|
Ok(match kind {
|
||||||
ProcessSpawnOptionsStdioKind::None => Vec::new(),
|
ProcessSpawnOptionsStdioKind::None | ProcessSpawnOptionsStdioKind::Forward => Vec::new(),
|
||||||
ProcessSpawnOptionsStdioKind::Forward => Vec::new(),
|
|
||||||
ProcessSpawnOptionsStdioKind::Default => {
|
ProcessSpawnOptionsStdioKind::Default => {
|
||||||
let mut read_from =
|
let mut read_from =
|
||||||
read_from.expect("read_from must be Some when stdio kind is Default");
|
read_from.expect("read_from must be Some when stdio kind is Default");
|
19
crates/lune-std-regex/Cargo.toml
Normal file
19
crates/lune-std-regex/Cargo.toml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
[package]
|
||||||
|
name = "lune-std-regex"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
license = "MPL-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
mlua = { version = "0.9.7", features = ["luau"] }
|
||||||
|
|
||||||
|
regex = "1.10"
|
||||||
|
self_cell = "1.0"
|
||||||
|
|
||||||
|
lune-utils = { version = "0.1.0", path = "../lune-utils" }
|
|
@ -1,8 +1,8 @@
|
||||||
#![allow(clippy::module_inception)]
|
#![allow(clippy::cargo_common_metadata)]
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
|
|
||||||
use crate::lune::util::TableBuilder;
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
mod captures;
|
mod captures;
|
||||||
mod matches;
|
mod matches;
|
||||||
|
@ -10,7 +10,14 @@ mod regex;
|
||||||
|
|
||||||
use self::regex::LuaRegex;
|
use self::regex::LuaRegex;
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<LuaTable> {
|
/**
|
||||||
|
Creates the `regex` standard library module.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
Errors when out of memory.
|
||||||
|
*/
|
||||||
|
pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
|
||||||
TableBuilder::new(lua)?
|
TableBuilder::new(lua)?
|
||||||
.with_function("new", new_regex)?
|
.with_function("new", new_regex)?
|
||||||
.build_readonly()
|
.build_readonly()
|
|
@ -46,7 +46,7 @@ impl LuaUserData for LuaRegex {
|
||||||
Ok(this
|
Ok(this
|
||||||
.inner
|
.inner
|
||||||
.split(&text)
|
.split(&text)
|
||||||
.map(|s| s.to_string())
|
.map(ToString::to_string)
|
||||||
.collect::<Vec<_>>())
|
.collect::<Vec<_>>())
|
||||||
});
|
});
|
||||||
|
|
21
crates/lune-std-roblox/Cargo.toml
Normal file
21
crates/lune-std-roblox/Cargo.toml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
[package]
|
||||||
|
name = "lune-std-roblox"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
license = "MPL-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
mlua = { version = "0.9.7", features = ["luau"] }
|
||||||
|
mlua-luau-scheduler = "0.0.2"
|
||||||
|
|
||||||
|
once_cell = "1.17"
|
||||||
|
rbx_cookie = { version = "0.1.4", default-features = false }
|
||||||
|
|
||||||
|
lune-utils = { version = "0.1.0", path = "../lune-utils" }
|
||||||
|
lune-roblox = { version = "0.1.0", path = "../lune-roblox" }
|
|
@ -1,23 +1,30 @@
|
||||||
|
#![allow(clippy::cargo_common_metadata)]
|
||||||
|
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use mlua_luau_scheduler::LuaSpawnExt;
|
use mlua_luau_scheduler::LuaSpawnExt;
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
|
|
||||||
use crate::{
|
use lune_roblox::{
|
||||||
lune::util::TableBuilder,
|
|
||||||
roblox::{
|
|
||||||
self,
|
|
||||||
document::{Document, DocumentError, DocumentFormat, DocumentKind},
|
document::{Document, DocumentError, DocumentFormat, DocumentKind},
|
||||||
instance::{registry::InstanceRegistry, Instance},
|
instance::{registry::InstanceRegistry, Instance},
|
||||||
reflection::Database as ReflectionDatabase,
|
reflection::Database as ReflectionDatabase,
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static REFLECTION_DATABASE: OnceCell<ReflectionDatabase> = OnceCell::new();
|
static REFLECTION_DATABASE: OnceCell<ReflectionDatabase> = OnceCell::new();
|
||||||
|
|
||||||
pub fn create(lua: &Lua) -> LuaResult<LuaTable> {
|
use lune_utils::TableBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates the `roblox` standard library module.
|
||||||
|
|
||||||
|
# Errors
|
||||||
|
|
||||||
|
Errors when out of memory.
|
||||||
|
*/
|
||||||
|
pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
|
||||||
let mut roblox_constants = Vec::new();
|
let mut roblox_constants = Vec::new();
|
||||||
|
|
||||||
let roblox_module = roblox::module(lua)?;
|
let roblox_module = lune_roblox::module(lua)?;
|
||||||
for pair in roblox_module.pairs::<LuaValue, LuaValue>() {
|
for pair in roblox_module.pairs::<LuaValue, LuaValue>() {
|
||||||
roblox_constants.push(pair?);
|
roblox_constants.push(pair?);
|
||||||
}
|
}
|
||||||
|
@ -116,16 +123,15 @@ fn implement_property(
|
||||||
Option<LuaFunction>,
|
Option<LuaFunction>,
|
||||||
),
|
),
|
||||||
) -> LuaResult<()> {
|
) -> LuaResult<()> {
|
||||||
let property_setter = match property_setter {
|
let property_setter = if let Some(setter) = property_setter {
|
||||||
Some(setter) => setter,
|
setter
|
||||||
None => {
|
} else {
|
||||||
let property_name = property_name.clone();
|
let property_name = property_name.clone();
|
||||||
lua.create_function(move |_, _: LuaMultiValue| {
|
lua.create_function(move |_, _: LuaMultiValue| {
|
||||||
Err::<(), _>(LuaError::runtime(format!(
|
Err::<(), _>(LuaError::runtime(format!(
|
||||||
"Property '{property_name}' is read-only"
|
"Property '{property_name}' is read-only"
|
||||||
)))
|
)))
|
||||||
})?
|
})?
|
||||||
}
|
|
||||||
};
|
};
|
||||||
InstanceRegistry::insert_property_getter(lua, &class_name, &property_name, property_getter)
|
InstanceRegistry::insert_property_getter(lua, &class_name, &property_name, property_getter)
|
||||||
.into_lua_err()?;
|
.into_lua_err()?;
|
35
crates/lune-std-serde/Cargo.toml
Normal file
35
crates/lune-std-serde/Cargo.toml
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
[package]
|
||||||
|
name = "lune-std-serde"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
license = "MPL-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
mlua = { version = "0.9.7", features = ["luau"] }
|
||||||
|
|
||||||
|
async-compression = { version = "0.4", features = [
|
||||||
|
"tokio",
|
||||||
|
"brotli",
|
||||||
|
"deflate",
|
||||||
|
"gzip",
|
||||||
|
"zlib",
|
||||||
|
] }
|
||||||
|
bstr = "1.9"
|
||||||
|
lz4 = "1.24"
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = { version = "1.0", features = ["preserve_order"] }
|
||||||
|
serde_yaml = "0.9"
|
||||||
|
toml = { version = "0.8", features = ["preserve_order"] }
|
||||||
|
|
||||||
|
tokio = { version = "1", default-features = false, features = [
|
||||||
|
"rt",
|
||||||
|
"io-util",
|
||||||
|
] }
|
||||||
|
|
||||||
|
lune-utils = { version = "0.1.0", path = "../lune-utils" }
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue