Merge branch 'main' into feature/sched-return

This commit is contained in:
Filip Tibell 2024-10-16 21:24:53 +02:00 committed by GitHub
commit 93cbe12afd
Signed by: DevComp
GPG key ID: B5690EEEBB952194
41 changed files with 840 additions and 714 deletions

View file

@ -23,11 +23,8 @@ jobs:
with:
components: rustfmt
- name: Install Just
uses: extractions/setup-just@v2
- name: Install Tooling
uses: ok-nick/setup-aftman@v0.4.2
uses: CompeyDev/setup-rokit@v0.1.0
- name: Check Formatting
run: just fmt-check
@ -40,11 +37,8 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Just
uses: extractions/setup-just@v2
- name: Install Tooling
uses: ok-nick/setup-aftman@v0.4.2
uses: CompeyDev/setup-rokit@v0.1.0
- name: Analyze
run: just analyze

View file

@ -27,26 +27,26 @@ jobs:
file: crates/lune/Cargo.toml
field: package.version
dry-run:
name: Dry-run
needs: ["init"]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
# dry-run:
# name: Dry-run
# needs: ["init"]
# runs-on: ubuntu-latest
# steps:
# - name: Checkout repository
# uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
# - name: 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 }}
# - 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"]
needs: ["init"] # , "dry-run"]
strategy:
fail-fast: false
matrix:
@ -112,7 +112,7 @@ jobs:
release-github:
name: Release (GitHub)
runs-on: ubuntu-latest
needs: ["init", "dry-run", "build"]
needs: ["init", "build"] # , "dry-run", "build"]
steps:
- name: Checkout repository
uses: actions/checkout@v4
@ -139,20 +139,20 @@ jobs:
files: ./releases/*.zip
draft: true
release-crates:
name: Release (crates.io)
runs-on: ubuntu-latest
needs: ["init", "dry-run", "build"]
steps:
- name: Checkout repository
uses: actions/checkout@v4
# 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: 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 }}
# - name: Publish crates
# uses: katyo/publish-crates@v2
# with:
# dry-run: false
# check-repo: true
# registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}

View file

@ -8,6 +8,41 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## `0.8.9` - October 7th, 2024
### Changed
- Updated to Luau version `0.640`
## `0.8.8` - August 22nd, 2024
### Fixed
- Fixed errors when deserializing `Lighting.AttributesSerialize` by updating `rbx-dom` dependencies ([#245])
[#245]: https://github.com/lune-org/lune/pull/245
## `0.8.7` - August 10th, 2024
### Added
- Added a compression level option to `serde.compress` ([#224])
- Added missing vector methods to the `roblox` library ([#228])
### Changed
- Updated to Luau version `0.635`
- Updated to rbx-dom database version `0.634`
### Fixed
- Fixed `fs.readDir` with trailing forward-slash on Windows ([#220])
- Fixed `__type` and `__tostring` metamethods not always being respected when formatting tables
[#220]: https://github.com/lune-org/lune/pull/220
[#224]: https://github.com/lune-org/lune/pull/224
[#228]: https://github.com/lune-org/lune/pull/228
## `0.8.6` - June 23rd, 2024
### Added

982
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,4 +0,0 @@
[tools]
luau-lsp = "JohnnyMorganz/luau-lsp@1.29.1"
selene = "Kampfkarren/selene@0.27.1"
stylua = "JohnnyMorganz/StyLua@0.20.0"

View file

@ -1,6 +1,6 @@
[package]
name = "lune-roblox"
version = "0.1.2"
version = "0.1.4"
edition = "2021"
license = "MPL-2.0"
repository = "https://github.com/lune-org/lune"
@ -13,17 +13,17 @@ path = "src/lib.rs"
workspace = true
[dependencies]
mlua = { version = "0.9.7", features = ["luau"] }
mlua = { version = "0.9.9", 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"
rbx_binary = "0.7.7"
rbx_dom_weak = "2.9.0"
rbx_reflection = "4.7.0"
rbx_reflection_database = "0.2.12"
rbx_xml = "0.13.5"
lune-utils = { version = "0.1.2", path = "../lune-utils" }
lune-utils = { version = "0.1.3", path = "../lune-utils" }

View file

@ -52,6 +52,9 @@ impl LuaUserData for Vector2 {
fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
// Methods
methods.add_method("Angle", |_, this, rhs: LuaUserDataRef<Vector2>| {
Ok(this.0.angle_between(rhs.0))
});
methods.add_method("Cross", |_, this, rhs: LuaUserDataRef<Vector2>| {
let this_v3 = Vec3::new(this.0.x, this.0.y, 0f32);
let rhs_v3 = Vec3::new(rhs.0.x, rhs.0.y, 0f32);
@ -60,6 +63,14 @@ impl LuaUserData for Vector2 {
methods.add_method("Dot", |_, this, rhs: LuaUserDataRef<Vector2>| {
Ok(this.0.dot(rhs.0))
});
methods.add_method(
"FuzzyEq",
|_, this, (rhs, epsilon): (LuaUserDataRef<Vector2>, f32)| {
let eq_x = (rhs.0.x - this.0.x).abs() <= epsilon;
let eq_y = (rhs.0.y - this.0.y).abs() <= epsilon;
Ok(eq_x && eq_y)
},
);
methods.add_method(
"Lerp",
|_, this, (rhs, alpha): (LuaUserDataRef<Vector2>, f32)| {
@ -72,6 +83,10 @@ impl LuaUserData for Vector2 {
methods.add_method("Min", |_, this, rhs: LuaUserDataRef<Vector2>| {
Ok(Vector2(this.0.min(rhs.0)))
});
methods.add_method("Abs", |_, this, ()| Ok(Vector2(this.0.abs())));
methods.add_method("Ceil", |_, this, ()| Ok(Vector2(this.0.ceil())));
methods.add_method("Floor", |_, this, ()| Ok(Vector2(this.0.floor())));
methods.add_method("Sign", |_, this, ()| Ok(Vector2(this.0.signum())));
// Metamethods
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);

View file

@ -133,6 +133,10 @@ impl LuaUserData for Vector3 {
methods.add_method("Min", |_, this, rhs: LuaUserDataRef<Vector3>| {
Ok(Vector3(this.0.min(rhs.0)))
});
methods.add_method("Abs", |_, this, ()| Ok(Vector3(this.0.abs())));
methods.add_method("Ceil", |_, this, ()| Ok(Vector3(this.0.ceil())));
methods.add_method("Floor", |_, this, ()| Ok(Vector3(this.0.floor())));
methods.add_method("Sign", |_, this, ()| Ok(Vector3(this.0.signum())));
// Metamethods
methods.add_meta_method(LuaMetaMethod::Eq, userdata_impl_eq);
methods.add_meta_method(LuaMetaMethod::ToString, userdata_impl_to_string);

View file

@ -26,7 +26,7 @@ pub fn add_methods<'lua, M: LuaUserDataMethods<'lua, Instance>>(m: &mut M) {
### See Also
* [`Terrain`](https://create.roblox.com/docs/reference/engine/classes/Workspace#Terrain)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
fn data_model_get_workspace(_: &Lua, this: &Instance) -> LuaResult<Instance> {
get_or_create_property_ref_instance(this, "Workspace", "Workspace")
@ -37,7 +37,7 @@ fn data_model_get_workspace(_: &Lua, this: &Instance) -> LuaResult<Instance> {
### See Also
* [`GetService`](https://create.roblox.com/docs/reference/engine/classes/ServiceProvider#GetService)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
fn data_model_get_service(_: &Lua, this: &Instance, service_name: String) -> LuaResult<Instance> {
if matches!(class_is_a_service(&service_name), None | Some(false)) {
@ -58,7 +58,7 @@ fn data_model_get_service(_: &Lua, this: &Instance, service_name: String) -> Lua
### See Also
* [`FindService`](https://create.roblox.com/docs/reference/engine/classes/ServiceProvider#FindService)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
fn data_model_find_service(
_: &Lua,

View file

@ -45,38 +45,26 @@ impl Instance {
Creates a new `Instance` from an existing dom object ref.
Panics if the instance does not exist in the internal dom,
or if the given dom object ref points to the dom root.
or if the given dom object ref points to the internal dom root.
**WARNING:** Creating a new instance requires locking the internal dom,
any existing lock must first be released to prevent any deadlocking.
*/
pub(crate) fn new(dom_ref: DomRef) -> Self {
let dom = INTERNAL_DOM.lock().expect("Failed to lock document");
let instance = dom
.get_by_ref(dom_ref)
.expect("Failed to find instance in document");
assert!(
!(instance.referent() == dom.root_ref()),
"Instances can not be created from dom roots"
);
Self {
dom_ref,
class_name: instance.class.clone(),
}
#[must_use]
pub fn new(dom_ref: DomRef) -> Self {
Self::new_opt(dom_ref).expect("Failed to find instance in document")
}
/**
Creates a new `Instance` from a dom object ref, if the instance exists.
Panics if the given dom object ref points to the dom root.
Panics if the given dom object ref points to the internal dom root.
**WARNING:** Creating a new instance requires locking the internal dom,
any existing lock must first be released to prevent any deadlocking.
*/
pub(crate) fn new_opt(dom_ref: DomRef) -> Option<Self> {
#[must_use]
pub fn new_opt(dom_ref: DomRef) -> Option<Self> {
let dom = INTERNAL_DOM.lock().expect("Failed to lock document");
if let Some(instance) = dom.get_by_ref(dom_ref) {
@ -97,12 +85,13 @@ impl Instance {
/**
Creates a new orphaned `Instance` with a given class name.
An orphaned instance is an instance at the root of a weak dom.
An orphaned instance is an instance at the root of Lune's internal weak dom.
**WARNING:** Creating a new instance requires locking the internal dom,
any existing lock must first be released to prevent any deadlocking.
*/
pub(crate) fn new_orphaned(class_name: impl AsRef<str>) -> Self {
#[must_use]
pub fn new_orphaned(class_name: impl AsRef<str>) -> Self {
let mut dom = INTERNAL_DOM.lock().expect("Failed to lock document");
let class_name = class_name.as_ref();
@ -122,10 +111,11 @@ impl Instance {
Creates a new orphaned `Instance` by transferring
it from an external weak dom to the internal one.
An orphaned instance is an instance at the root of a weak dom.
An orphaned instance is an instance at the root of Lune's internal weak dom.
Panics if the given dom ref is the root dom ref of the external weak dom.
*/
#[must_use]
pub fn from_external_dom(external_dom: &mut WeakDom, external_dom_ref: DomRef) -> Self {
let mut dom = INTERNAL_DOM.lock().expect("Failed to lock document");
let dom_root = dom.root_ref();
@ -151,6 +141,12 @@ impl Instance {
cloned
}
/**
Clones multiple instances to an external weak dom.
This will place the instances as children of the
root of the weak dom, and return their referents.
*/
pub fn clone_multiple_into_external_dom(
referents: &[DomRef],
external_dom: &mut WeakDom,
@ -174,7 +170,7 @@ impl Instance {
### See Also
* [`Clone`](https://create.roblox.com/docs/reference/engine/classes/Instance#Clone)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
#[must_use]
pub fn clone_instance(&self) -> Self {
@ -198,7 +194,7 @@ impl Instance {
### See Also
* [`Destroy`](https://create.roblox.com/docs/reference/engine/classes/Instance#Destroy)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn destroy(&mut self) -> bool {
if self.is_destroyed() {
@ -225,7 +221,7 @@ impl Instance {
### See Also
* [`Instance::Destroy`] for more info about what happens when an instance gets destroyed
* [`ClearAllChildren`](https://create.roblox.com/docs/reference/engine/classes/Instance#ClearAllChildren)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn clear_all_children(&mut self) {
let mut dom = INTERNAL_DOM.lock().expect("Failed to lock document");
@ -245,7 +241,7 @@ impl Instance {
### See Also
* [`IsA`](https://create.roblox.com/docs/reference/engine/classes/Instance#IsA)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn is_a(&self, class_name: impl AsRef<str>) -> bool {
class_is_a(&self.class_name, class_name).unwrap_or(false)
@ -258,7 +254,7 @@ impl Instance {
### See Also
* [`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 {
@ -270,7 +266,7 @@ impl Instance {
### See Also
* [`Name`](https://create.roblox.com/docs/reference/engine/classes/Instance#Name)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn get_name(&self) -> String {
let dom = INTERNAL_DOM.lock().expect("Failed to lock document");
@ -286,7 +282,7 @@ impl Instance {
### See Also
* [`Name`](https://create.roblox.com/docs/reference/engine/classes/Instance#Name)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn set_name(&self, name: impl Into<String>) {
let mut dom = INTERNAL_DOM.lock().expect("Failed to lock document");
@ -301,7 +297,7 @@ impl Instance {
### See Also
* [`Parent`](https://create.roblox.com/docs/reference/engine/classes/Instance#Parent)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn get_parent(&self) -> Option<Instance> {
let dom = INTERNAL_DOM.lock().expect("Failed to lock document");
@ -324,11 +320,11 @@ impl Instance {
If the provided parent is [`None`] the instance will become orphaned.
An orphaned instance is an instance at the root of a weak dom.
An orphaned instance is an instance at the root of Lune's internal weak dom.
### See Also
* [`Parent`](https://create.roblox.com/docs/reference/engine/classes/Instance#Parent)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn set_parent(&self, parent: Option<Instance>) {
let mut dom = INTERNAL_DOM.lock().expect("Failed to lock document");
@ -373,7 +369,7 @@ impl Instance {
### See Also
* [`GetAttribute`](https://create.roblox.com/docs/reference/engine/classes/Instance#GetAttribute)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn get_attribute(&self, name: impl AsRef<str>) -> Option<DomValue> {
let dom = INTERNAL_DOM.lock().expect("Failed to lock document");
@ -394,7 +390,7 @@ impl Instance {
### See Also
* [`GetAttributes`](https://create.roblox.com/docs/reference/engine/classes/Instance#GetAttributes)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn get_attributes(&self) -> BTreeMap<String, DomValue> {
let dom = INTERNAL_DOM.lock().expect("Failed to lock document");
@ -415,7 +411,7 @@ impl Instance {
### See Also
* [`SetAttribute`](https://create.roblox.com/docs/reference/engine/classes/Instance#SetAttribute)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn set_attribute(&self, name: impl AsRef<str>, value: DomValue) {
let mut dom = INTERNAL_DOM.lock().expect("Failed to lock document");
@ -470,7 +466,7 @@ impl Instance {
### See Also
* [`AddTag`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#AddTag)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn add_tag(&self, name: impl AsRef<str>) {
let mut dom = INTERNAL_DOM.lock().expect("Failed to lock document");
@ -492,7 +488,7 @@ impl Instance {
### See Also
* [`GetTags`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#GetTags)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn get_tags(&self) -> Vec<String> {
let dom = INTERNAL_DOM.lock().expect("Failed to lock document");
@ -511,7 +507,7 @@ impl Instance {
### See Also
* [`HasTag`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#HasTag)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn has_tag(&self, name: impl AsRef<str>) -> bool {
let dom = INTERNAL_DOM.lock().expect("Failed to lock document");
@ -531,7 +527,7 @@ impl Instance {
### See Also
* [`RemoveTag`](https://create.roblox.com/docs/reference/engine/classes/CollectionService#RemoveTag)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn remove_tag(&self, name: impl AsRef<str>) {
let mut dom = INTERNAL_DOM.lock().expect("Failed to lock document");
@ -557,7 +553,7 @@ impl Instance {
### See Also
* [`GetChildren`](https://create.roblox.com/docs/reference/engine/classes/Instance#GetChildren)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn get_children(&self) -> Vec<Instance> {
let dom = INTERNAL_DOM.lock().expect("Failed to lock document");
@ -580,7 +576,7 @@ impl Instance {
### See Also
* [`GetDescendants`](https://create.roblox.com/docs/reference/engine/classes/Instance#GetDescendants)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn get_descendants(&self) -> Vec<Instance> {
let dom = INTERNAL_DOM.lock().expect("Failed to lock document");
@ -614,7 +610,7 @@ impl Instance {
### See Also
* [`GetFullName`](https://create.roblox.com/docs/reference/engine/classes/Instance#GetFullName)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn get_full_name(&self) -> String {
let dom = INTERNAL_DOM.lock().expect("Failed to lock document");
@ -704,7 +700,7 @@ impl Instance {
### See Also
* [`FindFirstDescendant`](https://create.roblox.com/docs/reference/engine/classes/Instance#FindFirstDescendant)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
pub fn find_descendant<F>(&self, predicate: F) -> Option<Instance>
where

View file

@ -42,7 +42,7 @@ fn get_or_create_material_colors(instance: &Instance) -> MaterialColors {
### See Also
* [`GetMaterialColor`](https://create.roblox.com/docs/reference/engine/classes/Terrain#GetMaterialColor)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
fn terrain_get_material_color(_: &Lua, this: &Instance, material: EnumItem) -> LuaResult<Color3> {
let material_colors = get_or_create_material_colors(this);
@ -67,7 +67,7 @@ fn terrain_get_material_color(_: &Lua, this: &Instance, material: EnumItem) -> L
### See Also
* [`SetMaterialColor`](https://create.roblox.com/docs/reference/engine/classes/Terrain#SetMaterialColor)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
fn terrain_set_material_color(
_: &Lua,

View file

@ -16,7 +16,7 @@ pub fn add_fields<'lua, F: LuaUserDataFields<'lua, Instance>>(f: &mut F) {
### See Also
* [`Terrain`](https://create.roblox.com/docs/reference/engine/classes/Workspace#Terrain)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
fn workspace_get_terrain(_: &Lua, this: &Instance) -> LuaResult<Instance> {
get_or_create_property_ref_instance(this, "Terrain", "Terrain")
@ -27,7 +27,7 @@ fn workspace_get_terrain(_: &Lua, this: &Instance) -> LuaResult<Instance> {
### See Also
* [`CurrentCamera`](https://create.roblox.com/docs/reference/engine/classes/Workspace#CurrentCamera)
on the Roblox Developer Hub
on the Roblox Developer Hub
*/
fn workspace_get_camera(_: &Lua, this: &Instance) -> LuaResult<Instance> {
get_or_create_property_ref_instance(this, "CurrentCamera", "Camera")

View file

@ -1,6 +1,6 @@
[package]
name = "lune-std-datetime"
version = "0.1.2"
version = "0.1.3"
edition = "2021"
license = "MPL-2.0"
repository = "https://github.com/lune-org/lune"
@ -13,10 +13,10 @@ path = "src/lib.rs"
workspace = true
[dependencies]
mlua = { version = "0.9.7", features = ["luau"] }
mlua = { version = "0.9.9", features = ["luau"] }
thiserror = "1.0"
chrono = "0.4.38"
chrono_lc = "0.1.6"
lune-utils = { version = "0.1.2", path = "../lune-utils" }
lune-utils = { version = "0.1.3", path = "../lune-utils" }

View file

@ -1,6 +1,6 @@
[package]
name = "lune-std-fs"
version = "0.1.1"
version = "0.1.2"
edition = "2021"
license = "MPL-2.0"
repository = "https://github.com/lune-org/lune"
@ -13,11 +13,11 @@ path = "src/lib.rs"
workspace = true
[dependencies]
mlua = { version = "0.9.7", features = ["luau"] }
mlua = { version = "0.9.9", features = ["luau"] }
bstr = "1.9"
tokio = { version = "1", default-features = false, features = ["fs"] }
lune-utils = { version = "0.1.2", path = "../lune-utils" }
lune-std-datetime = { version = "0.1.1", path = "../lune-std-datetime" }
lune-utils = { version = "0.1.3", path = "../lune-utils" }
lune-std-datetime = { version = "0.1.2", path = "../lune-std-datetime" }

25
crates/lune-std-fs/src/lib.rs Normal file → Executable file
View file

@ -1,7 +1,7 @@
#![allow(clippy::cargo_common_metadata)]
use std::io::ErrorKind as IoErrorKind;
use std::path::{PathBuf, MAIN_SEPARATOR};
use std::path::PathBuf;
use bstr::{BString, ByteSlice};
use mlua::prelude::*;
@ -50,29 +50,16 @@ async fn fs_read_dir(_: &Lua, path: String) -> LuaResult<Vec<String>> {
let mut dir_strings = Vec::new();
let mut dir = fs::read_dir(&path).await.into_lua_err()?;
while let Some(dir_entry) = dir.next_entry().await.into_lua_err()? {
if let Some(dir_path_str) = dir_entry.path().to_str() {
dir_strings.push(dir_path_str.to_owned());
if let Some(dir_name_str) = dir_entry.file_name().to_str() {
dir_strings.push(dir_name_str.to_owned());
} else {
return Err(LuaError::RuntimeError(format!(
"File path could not be converted into a string: '{}'",
dir_entry.path().display()
"File name could not be converted into a string: '{}'",
dir_entry.file_name().to_string_lossy()
)));
}
}
let mut dir_string_prefix = path;
if !dir_string_prefix.ends_with(MAIN_SEPARATOR) {
dir_string_prefix.push(MAIN_SEPARATOR);
}
let dir_strings_no_prefix = dir_strings
.iter()
.map(|inner_path| {
inner_path
.trim()
.trim_start_matches(&dir_string_prefix)
.to_owned()
})
.collect::<Vec<_>>();
Ok(dir_strings_no_prefix)
Ok(dir_strings)
}
async fn fs_write_file(_: &Lua, (path, contents): (String, BString)) -> LuaResult<()> {

View file

@ -1,6 +1,6 @@
[package]
name = "lune-std-luau"
version = "0.1.1"
version = "0.1.2"
edition = "2021"
license = "MPL-2.0"
repository = "https://github.com/lune-org/lune"
@ -13,6 +13,6 @@ path = "src/lib.rs"
workspace = true
[dependencies]
mlua = { version = "0.9.7", features = ["luau", "luau-jit"] }
mlua = { version = "0.9.9", features = ["luau", "luau-jit"] }
lune-utils = { version = "0.1.2", path = "../lune-utils" }
lune-utils = { version = "0.1.3", path = "../lune-utils" }

View file

@ -1,6 +1,6 @@
[package]
name = "lune-std-net"
version = "0.1.1"
version = "0.1.2"
edition = "2021"
license = "MPL-2.0"
repository = "https://github.com/lune-org/lune"
@ -13,7 +13,7 @@ path = "src/lib.rs"
workspace = true
[dependencies]
mlua = { version = "0.9.7", features = ["luau"] }
mlua = { version = "0.9.9", features = ["luau"] }
mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" }
bstr = "1.9"
@ -35,5 +35,5 @@ tokio = { version = "1", default-features = false, features = [
"macros",
] }
lune-utils = { version = "0.1.2", path = "../lune-utils" }
lune-std-serde = { version = "0.1.1", path = "../lune-std-serde" }
lune-utils = { version = "0.1.3", path = "../lune-utils" }
lune-std-serde = { version = "0.1.2", path = "../lune-std-serde" }

View file

@ -18,6 +18,7 @@ impl LuaRequest {
let path = self.head.uri.path().to_string();
let body = lua.create_string(&self.body)?;
#[allow(clippy::mutable_key_type)]
let query: HashMap<LuaString, LuaString> = self
.head
.uri
@ -32,6 +33,7 @@ impl LuaRequest {
})
.collect::<LuaResult<_>>()?;
#[allow(clippy::mutable_key_type)]
let headers: HashMap<LuaString, LuaString> = self
.head
.headers

View file

@ -1,6 +1,6 @@
[package]
name = "lune-std-process"
version = "0.1.2"
version = "0.1.3"
edition = "2021"
license = "MPL-2.0"
repository = "https://github.com/lune-org/lune"
@ -13,7 +13,7 @@ path = "src/lib.rs"
workspace = true
[dependencies]
mlua = { version = "0.9.7", features = ["luau"] }
mlua = { version = "0.9.9", features = ["luau"] }
mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" }
directories = "5.0"
@ -28,4 +28,4 @@ tokio = { version = "1", default-features = false, features = [
"sync",
] }
lune-utils = { version = "0.1.2", path = "../lune-utils" }
lune-utils = { version = "0.1.3", path = "../lune-utils" }

View file

@ -42,8 +42,8 @@ pub fn module(lua: &Lua) -> LuaResult<LuaTable> {
cwd_str.push(MAIN_SEPARATOR);
}
// Create constants for OS & processor architecture
let os = lua.create_string(&OS.to_lowercase())?;
let arch = lua.create_string(&ARCH.to_lowercase())?;
let os = lua.create_string(OS.to_lowercase())?;
let arch = lua.create_string(ARCH.to_lowercase())?;
// Create readonly args array
let args_vec = lua
.app_data_ref::<Vec<String>>()

View file

@ -1,6 +1,6 @@
[package]
name = "lune-std-regex"
version = "0.1.1"
version = "0.1.2"
edition = "2021"
license = "MPL-2.0"
repository = "https://github.com/lune-org/lune"
@ -13,9 +13,9 @@ path = "src/lib.rs"
workspace = true
[dependencies]
mlua = { version = "0.9.7", features = ["luau"] }
mlua = { version = "0.9.9", features = ["luau"] }
regex = "1.10"
self_cell = "1.0"
lune-utils = { version = "0.1.2", path = "../lune-utils" }
lune-utils = { version = "0.1.3", path = "../lune-utils" }

View file

@ -1,6 +1,6 @@
[package]
name = "lune-std-roblox"
version = "0.1.2"
version = "0.1.4"
edition = "2021"
license = "MPL-2.0"
repository = "https://github.com/lune-org/lune"
@ -13,11 +13,11 @@ path = "src/lib.rs"
workspace = true
[dependencies]
mlua = { version = "0.9.7", features = ["luau"] }
mlua = { version = "0.9.9", features = ["luau"] }
mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" }
once_cell = "1.17"
rbx_cookie = { version = "0.1.4", default-features = false }
lune-utils = { version = "0.1.2", path = "../lune-utils" }
lune-roblox = { version = "0.1.2", path = "../lune-roblox" }
lune-utils = { version = "0.1.3", path = "../lune-utils" }
lune-roblox = { version = "0.1.4", path = "../lune-roblox" }

View file

@ -1,6 +1,6 @@
[package]
name = "lune-std-serde"
version = "0.1.1"
version = "0.1.2"
edition = "2021"
license = "MPL-2.0"
repository = "https://github.com/lune-org/lune"
@ -13,7 +13,7 @@ path = "src/lib.rs"
workspace = true
[dependencies]
mlua = { version = "0.9.7", features = ["luau", "serialize"] }
mlua = { version = "0.9.9", features = ["luau", "serialize"] }
async-compression = { version = "0.4", features = [
"tokio",
@ -23,7 +23,7 @@ async-compression = { version = "0.4", features = [
"zlib",
] }
bstr = "1.9"
lz4 = "1.24"
lz4 = "1.26"
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0", features = ["preserve_order"] }
serde_yaml = "0.9"
@ -44,4 +44,4 @@ tokio = { version = "1", default-features = false, features = [
"io-util",
] }
lune-utils = { version = "0.1.2", path = "../lune-utils" }
lune-utils = { version = "0.1.3", path = "../lune-utils" }

View file

@ -13,6 +13,7 @@ use async_compression::{
BrotliDecoder, BrotliEncoder, GzipDecoder, GzipEncoder, ZlibDecoder, ZlibEncoder,
},
Level::Best as CompressionQuality,
Level::Precise as PreciseCompressionQuality,
};
/**
@ -119,6 +120,7 @@ impl<'lua> FromLua<'lua> for CompressDecompressFormat {
pub async fn compress<'lua>(
source: impl AsRef<[u8]>,
format: CompressDecompressFormat,
level: Option<i32>,
) -> LuaResult<Vec<u8>> {
if let CompressDecompressFormat::LZ4 = format {
let source = source.as_ref().to_vec();
@ -130,18 +132,22 @@ pub async fn compress<'lua>(
let mut bytes = Vec::new();
let reader = BufReader::new(source.as_ref());
let compression_quality = match level {
Some(l) => PreciseCompressionQuality(l),
None => CompressionQuality,
};
match format {
CompressDecompressFormat::Brotli => {
let mut encoder = BrotliEncoder::with_quality(reader, CompressionQuality);
let mut encoder = BrotliEncoder::with_quality(reader, compression_quality);
copy(&mut encoder, &mut bytes).await?;
}
CompressDecompressFormat::GZip => {
let mut encoder = GzipEncoder::with_quality(reader, CompressionQuality);
let mut encoder = GzipEncoder::with_quality(reader, compression_quality);
copy(&mut encoder, &mut bytes).await?;
}
CompressDecompressFormat::ZLib => {
let mut encoder = ZlibEncoder::with_quality(reader, CompressionQuality);
let mut encoder = ZlibEncoder::with_quality(reader, compression_quality);
copy(&mut encoder, &mut bytes).await?;
}
CompressDecompressFormat::LZ4 => unreachable!(),

View file

@ -46,9 +46,9 @@ fn serde_decode(lua: &Lua, (format, bs): (EncodeDecodeFormat, BString)) -> LuaRe
async fn serde_compress(
lua: &Lua,
(format, bs): (CompressDecompressFormat, BString),
(format, bs, level): (CompressDecompressFormat, BString, Option<i32>),
) -> LuaResult<LuaString> {
let bytes = compress(bs, format).await?;
let bytes = compress(bs, format, level).await?;
lua.create_string(bytes)
}

View file

@ -1,6 +1,6 @@
[package]
name = "lune-std-stdio"
version = "0.1.1"
version = "0.1.2"
edition = "2021"
license = "MPL-2.0"
repository = "https://github.com/lune-org/lune"
@ -14,7 +14,7 @@ workspace = true
[dependencies]
dialoguer = "0.11"
mlua = { version = "0.9.7", features = ["luau"] }
mlua = { version = "0.9.9", features = ["luau"] }
mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" }
tokio = { version = "1", default-features = false, features = [
@ -22,4 +22,4 @@ tokio = { version = "1", default-features = false, features = [
"io-util",
] }
lune-utils = { version = "0.1.2", path = "../lune-utils" }
lune-utils = { version = "0.1.3", path = "../lune-utils" }

View file

@ -194,14 +194,14 @@ pub fn prompt(options: PromptOptions) -> LuaResult<PromptResult> {
prompt = prompt.default(b);
};
let result = prompt
.with_prompt(&options.text.expect("Missing text in prompt options"))
.with_prompt(options.text.expect("Missing text in prompt options"))
.interact()
.into_lua_err()?;
Ok(PromptResult::Boolean(result))
}
PromptKind::Select => {
let chosen = Select::with_theme(&theme)
.with_prompt(&options.text.unwrap_or_default())
.with_prompt(options.text.unwrap_or_default())
.items(&options.options.expect("Missing options in prompt options"))
.interact_opt()
.into_lua_err()?;
@ -212,7 +212,7 @@ pub fn prompt(options: PromptOptions) -> LuaResult<PromptResult> {
}
PromptKind::MultiSelect => {
let chosen = MultiSelect::with_theme(&theme)
.with_prompt(&options.text.unwrap_or_default())
.with_prompt(options.text.unwrap_or_default())
.items(&options.options.expect("Missing options in prompt options"))
.interact_opt()
.into_lua_err()?;

View file

@ -1,6 +1,6 @@
[package]
name = "lune-std-task"
version = "0.1.1"
version = "0.1.2"
edition = "2021"
license = "MPL-2.0"
repository = "https://github.com/lune-org/lune"
@ -13,9 +13,9 @@ path = "src/lib.rs"
workspace = true
[dependencies]
mlua = { version = "0.9.7", features = ["luau"] }
mlua = { version = "0.9.9", features = ["luau"] }
mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" }
tokio = { version = "1", default-features = false, features = ["time"] }
lune-utils = { version = "0.1.2", path = "../lune-utils" }
lune-utils = { version = "0.1.3", path = "../lune-utils" }

View file

@ -1,6 +1,6 @@
[package]
name = "lune-std"
version = "0.1.3"
version = "0.1.5"
edition = "2021"
license = "MPL-2.0"
repository = "https://github.com/lune-org/lune"
@ -38,22 +38,22 @@ stdio = ["dep:lune-std-stdio"]
task = ["dep:lune-std-task"]
[dependencies]
mlua = { version = "0.9.7", features = ["luau"] }
mlua = { version = "0.9.9", features = ["luau"] }
mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tokio = { version = "1", default-features = false, features = ["fs", "sync"] }
lune-utils = { version = "0.1.2", path = "../lune-utils" }
lune-utils = { version = "0.1.3", path = "../lune-utils" }
lune-std-datetime = { optional = true, version = "0.1.2", path = "../lune-std-datetime" }
lune-std-fs = { optional = true, version = "0.1.1", path = "../lune-std-fs" }
lune-std-luau = { optional = true, version = "0.1.1", path = "../lune-std-luau" }
lune-std-net = { optional = true, version = "0.1.1", path = "../lune-std-net" }
lune-std-process = { optional = true, version = "0.1.2", path = "../lune-std-process" }
lune-std-regex = { optional = true, version = "0.1.1", path = "../lune-std-regex" }
lune-std-roblox = { optional = true, version = "0.1.2", path = "../lune-std-roblox" }
lune-std-serde = { optional = true, version = "0.1.1", path = "../lune-std-serde" }
lune-std-stdio = { optional = true, version = "0.1.1", path = "../lune-std-stdio" }
lune-std-task = { optional = true, version = "0.1.1", path = "../lune-std-task" }
lune-std-datetime = { optional = true, version = "0.1.3", path = "../lune-std-datetime" }
lune-std-fs = { optional = true, version = "0.1.2", path = "../lune-std-fs" }
lune-std-luau = { optional = true, version = "0.1.2", path = "../lune-std-luau" }
lune-std-net = { optional = true, version = "0.1.2", path = "../lune-std-net" }
lune-std-process = { optional = true, version = "0.1.3", path = "../lune-std-process" }
lune-std-regex = { optional = true, version = "0.1.2", path = "../lune-std-regex" }
lune-std-roblox = { optional = true, version = "0.1.4", path = "../lune-std-roblox" }
lune-std-serde = { optional = true, version = "0.1.2", path = "../lune-std-serde" }
lune-std-stdio = { optional = true, version = "0.1.2", path = "../lune-std-stdio" }
lune-std-task = { optional = true, version = "0.1.2", path = "../lune-std-task" }

View file

@ -1,6 +1,6 @@
[package]
name = "lune-utils"
version = "0.1.2"
version = "0.1.3"
edition = "2021"
license = "MPL-2.0"
repository = "https://github.com/lune-org/lune"
@ -13,7 +13,7 @@ path = "src/lib.rs"
workspace = true
[dependencies]
mlua = { version = "0.9.7", features = ["luau", "async"] }
mlua = { version = "0.9.9", features = ["luau", "async"] }
tokio = { version = "1", default-features = false, features = ["fs"] }

View file

@ -4,6 +4,7 @@ use std::fmt::{self, Write as _};
use mlua::prelude::*;
use super::metamethods::{call_table_tostring_metamethod, get_table_type_metavalue};
use super::{
basic::{format_value_styled, lua_value_as_plain_string_key},
config::ValueFormatConfig,
@ -46,7 +47,12 @@ pub(crate) fn format_value_recursive(
let mut buffer = String::new();
if let LuaValue::Table(ref t) = value {
if depth >= config.max_depth {
if let Some(formatted) = format_typename_and_tostringed(
get_table_type_metavalue(t),
call_table_tostring_metamethod(t),
) {
write!(buffer, "{formatted}")?;
} else if depth >= config.max_depth {
write!(buffer, "{}", STYLE_DIM.apply_to("{ ... }"))?;
} else if !visited.insert(LuaValueId::from(t)) {
write!(buffer, "{}", STYLE_DIM.apply_to("{ recursive }"))?;
@ -164,3 +170,15 @@ fn format_table(
})
.collect()
}
fn format_typename_and_tostringed(
typename: Option<String>,
tostringed: Option<String>,
) -> Option<String> {
match (typename, tostringed) {
(Some(typename), Some(tostringed)) => Some(format!("<{typename}({tostringed})>")),
(Some(typename), None) => Some(format!("<{typename}>")),
(None, Some(tostringed)) => Some(tostringed),
(None, None) => None,
}
}

View file

@ -1,6 +1,6 @@
[package]
name = "lune"
version = "0.8.6"
version = "0.8.9"
edition = "2021"
license = "MPL-2.0"
repository = "https://github.com/lune-org/lune"
@ -50,7 +50,7 @@ cli = ["dep:clap", "dep:include_dir", "dep:rustyline", "dep:zip_next"]
workspace = true
[dependencies]
mlua = { version = "0.9.7", features = ["luau"] }
mlua = { version = "0.9.9", features = ["luau"] }
mlua-luau-scheduler = { version = "0.0.2", path = "../mlua-luau-scheduler" }
anyhow = "1.0"
@ -71,9 +71,9 @@ reqwest = { version = "0.11", default-features = false, features = [
"rustls-tls",
] }
lune-std = { optional = true, version = "0.1.3", path = "../lune-std" }
lune-roblox = { optional = true, version = "0.1.2", path = "../lune-roblox" }
lune-utils = { version = "0.1.2", path = "../lune-utils" }
lune-std = { optional = true, version = "0.1.5", path = "../lune-std" }
lune-roblox = { optional = true, version = "0.1.4", path = "../lune-roblox" }
lune-utils = { version = "0.1.3", path = "../lune-utils" }
### CLI

View file

@ -25,7 +25,7 @@ futures-lite = "2.2"
rustc-hash = "1.1"
tracing = "0.1"
mlua = { version = "0.9.6", features = [
mlua = { version = "0.9.9", features = [
"luau",
"luau-jit",
"async",

4
rokit.toml Normal file
View file

@ -0,0 +1,4 @@
[tools]
luau-lsp = "JohnnyMorganz/luau-lsp@1.32.1"
stylua = "JohnnyMorganz/StyLua@0.20.0"
just = "casey/just@1.34.0"

View file

@ -1,6 +0,0 @@
std = "luau+lune"
exclude = ["luneTypes.d.luau"]
[lints]
high_cyclomatic_complexity = "warn"

View file

@ -42,4 +42,14 @@ assert(Vector2.new(2, 4) / 2 == Vector2.new(1, 2))
assert(Vector2.new(7, 15) // Vector2.new(3, 7) == Vector2.new(2, 2))
assert(Vector2.new(3, 7) // 2 == Vector2.new(1, 3))
-- TODO: Vector math
-- Vector math methods
assert(Vector2.new(-1, -2):Abs() == Vector2.new(1, 2))
assert(Vector2.new(-1.7, 2):Sign() == Vector2.new(-1, 1))
assert(Vector2.new(-1.9, 2.1):Ceil() == Vector2.new(-1, 3))
assert(Vector2.new(-1.1, 2.99):Floor() == Vector2.new(-2, 2))
assert(Vector2.new(1, 2):FuzzyEq(Vector2.new(1 - 1e-6, 2 + 1e-6), 1e-5))
assert(not Vector2.new(1, 2):FuzzyEq(Vector2.new(1.2, 2), 0.1))
local angle = Vector2.new(1, 1):Angle(Vector2.new(-1, 1))
assert(math.abs(angle - (math.pi / 2)) < 1e-5)

View file

@ -45,4 +45,10 @@ assert(Vector3.new(2, 4, 8) / 2 == Vector3.new(1, 2, 4))
assert(Vector3.new(7, 11, 15) // Vector3.new(3, 5, 7) == Vector3.new(2, 2, 2))
assert(Vector3.new(3, 5, 7) // 2 == Vector3.new(1, 2, 3))
-- TODO: Vector math
-- Vector math methods
assert(Vector3.new(-1, -2, -3):Abs() == Vector3.new(1, 2, 3))
assert(Vector3.new(-1.7, 2, -3):Sign() == Vector3.new(-1, 1, -1))
assert(Vector3.new(-1.9, 2.1, 3.5):Ceil() == Vector3.new(-1, 3, 4))
assert(Vector3.new(-1.1, 2.99, 3.5):Floor() == Vector3.new(-2, 2, 3))
assert(Vector3.new(1, 2, 3):FuzzyEq(Vector3.new(1 - 1e-6, 2 + 1e-6, 3 + 1e-6), 1e-5))

View file

@ -87,10 +87,19 @@ export type DateTimeValueArguments = DateTimeValues & OptionalMillisecond
]=]
export type DateTimeValueReturns = DateTimeValues & Millisecond
--[=[
@prop unixTimestamp number
@within DateTime
Number of seconds passed since the UNIX epoch.
]=]
--[=[
@prop unixTimestampMillis number
@within DateTime
Number of milliseconds passed since the UNIX epoch.
]=]
local DateTime = {
--- Number of seconds passed since the UNIX epoch.
unixTimestamp = (nil :: any) :: number,
--- Number of milliseconds passed since the UNIX epoch.
unixTimestampMillis = (nil :: any) :: number,
}

View file

@ -19,67 +19,82 @@ local RegexMatch = {
type RegexMatch = typeof(RegexMatch)
local RegexCaptures = {}
function RegexCaptures.get(self: RegexCaptures, index: number): RegexMatch?
return nil :: any
end
function RegexCaptures.group(self: RegexCaptures, group: string): RegexMatch?
return nil :: any
end
function RegexCaptures.format(self: RegexCaptures, format: string): string
return nil :: any
end
--[=[
@class RegexCaptures
Captures from a regular expression.
]=]
local RegexCaptures = {}
export type RegexCaptures = typeof(setmetatable(
{} :: {
--[=[
@within RegexCaptures
@tag Method
@method get
--[=[
@within RegexCaptures
@tag Method
Returns the match at the given index, if one exists.
Returns the match at the given index, if one exists.
@param index -- The index of the match to get
@return RegexMatch -- The match, if one exists
]=]
@param index -- The index of the match to get
@return RegexMatch -- The match, if one exists
]=]
function RegexCaptures.get(self: RegexCaptures, index: number): RegexMatch?
return nil :: any
end
get: (self: RegexCaptures, index: number) -> RegexMatch?,
--[=[
@within RegexCaptures
@tag Method
--[=[
@within RegexCaptures
@tag Method
@method group
Returns the match for the given named match group, if one exists.
Returns the match for the given named match group, if one exists.
@param group -- The name of the group to get
@return RegexMatch -- The match, if one exists
]=]
function RegexCaptures.group(self: RegexCaptures, group: string): RegexMatch?
return nil :: any
end
@param group -- The name of the group to get
@return RegexMatch -- The match, if one exists
]=]
group: (self: RegexCaptures, group: string) -> RegexMatch?,
--[=[
@within RegexCaptures
@tag Method
--[=[
@within RegexCaptures
@tag Method
@method format
Formats the captures using the given format string.
Formats the captures using the given format string.
### Example usage
### Example usage
```lua
local regex = require("@lune/regex")
```lua
local regex = require("@lune/regex")
local re = regex.new("(?<day>[0-9]{2})-(?<month>[0-9]{2})-(?<year>[0-9]{4})")
local re = regex.new("(?<day>[0-9]{2})-(?<month>[0-9]{2})-(?<year>[0-9]{4})")
local caps = re:captures("On 14-03-2010, I became a Tenneessee lamb.");
assert(caps ~= nil, "Example pattern should match example text")
local caps = re:captures("On 14-03-2010, I became a Tenneessee lamb.");
assert(caps ~= nil, "Example pattern should match example text")
local formatted = caps:format("year=$year, month=$month, day=$day")
print(formatted) -- "year=2010, month=03, day=14"
```
local formatted = caps:format("year=$year, month=$month, day=$day")
print(formatted) -- "year=2010, month=03, day=14"
```
@param format -- The format string to use
@return string -- The formatted string
]=]
function RegexCaptures.format(self: RegexCaptures, format: string): string
return nil :: any
end
export type RegexCaptures = typeof(RegexCaptures)
@param format -- The format string to use
@return string -- The formatted string
]=]
format: (self: RegexCaptures, format: string) -> string,
},
{} :: {
__len: (self: RegexCaptures) -> number,
}
))
local Regex = {}

View file

@ -136,9 +136,10 @@ end
@param format The format to use
@param s The string to compress
@param level The compression level to use, clamped to the format's limits. The best compression level is used by default
@return The compressed string
]=]
function serde.compress(format: CompressDecompressFormat, s: buffer | string): string
function serde.compress(format: CompressDecompressFormat, s: buffer | string, level: number?): string
return nil :: any
end