Skip to content

Commit 6e2b687

Browse files
committed
Serde support (serialize feature flag)
1 parent 661f8e5 commit 6e2b687

File tree

17 files changed

+1690
-68
lines changed

17 files changed

+1690
-68
lines changed

.github/workflows/main.yml

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
- name: Build ${{ matrix.lua }} vendored
2828
run: |
2929
cargo build --release --features "${{ matrix.lua }} vendored"
30-
cargo build --release --features "${{ matrix.lua }} vendored async send"
30+
cargo build --release --features "${{ matrix.lua }} vendored async send serialize"
3131
shell: bash
3232
- name: Build ${{ matrix.lua }} pkg-config
3333
if: ${{ matrix.os == 'ubuntu-18.04' && matrix.lua != 'lua54' }}
@@ -63,13 +63,13 @@ jobs:
6363
if: ${{ matrix.os != 'macos-latest' || matrix.lua != 'luajit' }}
6464
run: |
6565
cargo test --release --features "${{ matrix.lua }} vendored"
66-
cargo test --release --features "${{ matrix.lua }} vendored async send"
66+
cargo test --release --features "${{ matrix.lua }} vendored async send serialize"
6767
shell: bash
6868
- name: Run compile tests (macos lua53)
6969
if: ${{ matrix.os == 'macos-latest' && matrix.lua == 'lua53' }}
7070
run: |
7171
TRYBUILD=overwrite cargo test --release --features "${{ matrix.lua }} vendored" -- --ignored
72-
TRYBUILD=overwrite cargo test --release --features "${{ matrix.lua }} vendored async send" -- --ignored
72+
TRYBUILD=overwrite cargo test --release --features "${{ matrix.lua }} vendored async send serialize" -- --ignored
7373
shell: bash
7474

7575
test_luajit_macos:
@@ -85,12 +85,12 @@ jobs:
8585
override: true
8686
- name: Run LuaJIT 2.0.5 tests
8787
run: |
88-
brew install luajit pkg-config
89-
cargo test --tests --release --features "luajit async send" -- --test-threads=1
88+
brew install luajit
89+
cargo test --tests --release --features "luajit async send serialize" -- --test-threads=1
9090
shell: bash
9191
- name: Run LuaJIT vendored tests
9292
run: |
93-
cargo test --release --features "luajit vendored async send"
93+
cargo test --release --features "luajit vendored async send serialize"
9494
shell: bash
9595

9696
test_modules:
@@ -126,21 +126,16 @@ jobs:
126126
needs: build
127127
strategy:
128128
matrix:
129-
lua: [lua53, lua51, luajit]
129+
lua: [lua53, luajit]
130130
defaults:
131131
run:
132-
shell: bash.exe --login -eo pipefail "{0}"
133-
env:
134-
MSYSTEM: MINGW64
135-
CHERE_INVOKING: 1
132+
shell: msys2 {0}
136133
steps:
134+
- uses: msys2/setup-msys2@v2
137135
- uses: actions/checkout@v2
138-
- name: Set up shell
139-
run: echo ::add-path::C:\msys64\usr\bin\
140-
shell: pwsh
141136
- name: Install Rust & Lua
142137
run: |
143-
pacman -S --noconfirm mingw-w64-x86_64-rust mingw-w64-x86_64-lua mingw-w64-x86_64-lua51 mingw-w64-x86_64-luajit
138+
pacman -S --noconfirm mingw-w64-x86_64-rust mingw-w64-x86_64-lua mingw-w64-x86_64-luajit mingw-w64-x86_64-pkg-config
144139
- name: Run ${{ matrix.lua }} module tests
145140
run: |
146141
(cd examples/module && cargo build --release --features "${{ matrix.lua }}")
@@ -174,4 +169,4 @@ jobs:
174169
- uses: actions-rs/clippy-check@v1
175170
with:
176171
token: ${{ secrets.GITHUB_TOKEN }}
177-
args: --features "${{ matrix.lua }},async,send,vendored
172+
args: --features "${{ matrix.lua }},vendored,async,send,serialize

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ vendored = ["lua-src", "luajit-src"]
4040
module = []
4141
async = ["futures-core", "futures-task", "futures-util"]
4242
send = []
43+
serialize = ["serde", "erased-serde"]
4344

4445
[dependencies]
4546
bstr = { version = "0.2", features = ["std"], default_features = false }
@@ -48,6 +49,8 @@ num-traits = { version = "0.2.14" }
4849
futures-core = { version = "0.3.5", optional = true }
4950
futures-task = { version = "0.3.5", optional = true }
5051
futures-util = { version = "0.3.5", optional = true }
52+
serde = { version = "1.0", optional = true }
53+
erased-serde = { version = "0.3", optional = true }
5154

5255
[build-dependencies]
5356
cc = { version = "1.0" }
@@ -63,6 +66,7 @@ futures = "0.3.5"
6366
hyper = "0.13"
6467
tokio = { version = "0.2", features = ["full"] }
6568
futures-timer = "3.0"
69+
serde_json = "1.0"
6670

6771
[[bench]]
6872
name = "benchmark"

src/error.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ pub enum Error {
105105
/// [`AnyUserData`]: struct.AnyUserData.html
106106
/// [`UserDataMethods`]: trait.UserDataMethods.html
107107
UserDataTypeMismatch,
108+
/// An [`AnyUserData`] borrow failed because it has been destructed.
109+
///
110+
/// This error can happen either due to to being destructed in a previous __gc, or due to being
111+
/// destructed from exiting a `Lua::scope` call.
112+
UserDataDestructed,
108113
/// An [`AnyUserData`] immutable borrow failed because it is already borrowed mutably.
109114
///
110115
/// This error can occur when a method on a [`UserData`] type calls back into Lua, which then
@@ -132,6 +137,12 @@ pub enum Error {
132137
/// Original error returned by the Rust code.
133138
cause: Arc<Error>,
134139
},
140+
/// Serialization error.
141+
#[cfg(feature = "serialize")]
142+
SerializeError(StdString),
143+
/// Deserialization error.
144+
#[cfg(feature = "serialize")]
145+
DeserializeError(StdString),
135146
/// A custom error.
136147
///
137148
/// This can be used for returning user-defined errors from callbacks.
@@ -206,6 +217,7 @@ impl fmt::Display for Error {
206217
}
207218
Error::CoroutineInactive => write!(fmt, "cannot resume inactive coroutine"),
208219
Error::UserDataTypeMismatch => write!(fmt, "userdata is not expected type"),
220+
Error::UserDataDestructed => write!(fmt, "userdata has been destructed"),
209221
Error::UserDataBorrowError => write!(fmt, "userdata already mutably borrowed"),
210222
Error::UserDataBorrowMutError => write!(fmt, "userdata already borrowed"),
211223
Error::MismatchedRegistryKey => {
@@ -214,6 +226,14 @@ impl fmt::Display for Error {
214226
Error::CallbackError { ref traceback, .. } => {
215227
write!(fmt, "callback error: {}", traceback)
216228
}
229+
#[cfg(feature = "serialize")]
230+
Error::SerializeError(ref err) => {
231+
write!(fmt, "serialize error: {}", err)
232+
},
233+
#[cfg(feature = "serialize")]
234+
Error::DeserializeError(ref err) => {
235+
write!(fmt, "deserialize error: {}", err)
236+
},
217237
Error::ExternalError(ref err) => write!(fmt, "{}", err),
218238
}
219239
}
@@ -289,3 +309,17 @@ impl std::convert::From<Utf8Error> for Error {
289309
Error::external(err)
290310
}
291311
}
312+
313+
#[cfg(feature = "serialize")]
314+
impl serde::ser::Error for Error {
315+
fn custom<T: fmt::Display>(msg: T) -> Self {
316+
Self::SerializeError(msg.to_string())
317+
}
318+
}
319+
320+
#[cfg(feature = "serialize")]
321+
impl serde::de::Error for Error {
322+
fn custom<T: fmt::Display>(msg: T) -> Self {
323+
Self::DeserializeError(msg.to_string())
324+
}
325+
}

src/hook.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ impl<'a> Debug<'a> {
3737
}
3838
}
3939

40-
/// Corresponds to the `n` what mask.
40+
/// Corresponds to the `S` what mask.
4141
pub fn source(&self) -> DebugSource<'a> {
4242
unsafe {
4343
mlua_assert!(

src/lib.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@
2424
//! The [`UserData`] trait can be implemented by user-defined types to make them available to Lua.
2525
//! Methods and operators to be used from Lua can be added using the [`UserDataMethods`] API.
2626
//!
27+
//! # Serde support
28+
//!
29+
//! The [`LuaSerdeExt`] trait implemented for [`Lua`] allow conversion from Rust types to Lua values
30+
//! and vice versa using serde. Any user defined data type that implements `serde::Serialize` or
31+
//! `serde::Deserialize` can be converted.
32+
//! For convenience, additional functionality to handle NULL values and arrays is provided.
33+
//!
34+
//! The [`Value`] struct implements `serde::Serialize` trait to support serializing Lua values
35+
//! (including [`UserData`]) into Rust values.
36+
//!
37+
//! Requires `feature = "serialize"`.
38+
//!
2739
//! # Async/await support
2840
//!
2941
//! The [`create_async_function`] allows creating non-blocking functions that returns [`Future`].
@@ -47,6 +59,8 @@
4759
//! [`FromLuaMulti`]: trait.FromLuaMulti.html
4860
//! [`UserData`]: trait.UserData.html
4961
//! [`UserDataMethods`]: trait.UserDataMethods.html
62+
//! [`LuaSerdeExt`]: trait.LuaSerdeExt.html
63+
//! [`Value`]: struct.Value.html
5064
//! [`create_async_function`]: struct.Lua.html#method.create_async_function
5165
//! [`call_async`]: struct.Function.html#method.call_async
5266
//! [`AsyncThread`]: struct.AsyncThread.html
@@ -95,4 +109,9 @@ pub use crate::value::{FromLua, FromLuaMulti, MultiValue, Nil, ToLua, ToLuaMulti
95109
#[cfg(feature = "async")]
96110
pub use crate::thread::AsyncThread;
97111

112+
#[cfg(feature = "serialize")]
113+
pub use crate::serde::LuaSerdeExt;
114+
98115
pub mod prelude;
116+
#[cfg(feature = "serialize")]
117+
pub mod serde;

0 commit comments

Comments
 (0)