Skip to content

Commit fb0c0d9

Browse files
committed
Add Either<L, R> enum to combine two types into a single one.
It implements `FromLua` and `IntoLua` traits for easy type conversions..
1 parent 235c320 commit fb0c0d9

File tree

11 files changed

+278
-47
lines changed

11 files changed

+278
-47
lines changed

mlua_derive/src/from_lua.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub fn from_lua(input: TokenStream) -> TokenStream {
2020
::mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
2121
_ => Err(::mlua::Error::FromLuaConversionError {
2222
from: value.type_name(),
23-
to: #ident_str,
23+
to: #ident_str.to_string(),
2424
message: None,
2525
}),
2626
}

src/conversion.rs

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::state::{Lua, RawLua};
1515
use crate::string::String;
1616
use crate::table::Table;
1717
use crate::thread::Thread;
18+
use crate::traits::ShortTypeName as _;
1819
use crate::types::{LightUserData, MaybeSend, RegistryKey};
1920
use crate::userdata::{AnyUserData, UserData};
2021
use crate::value::{FromLua, IntoLua, Nil, Value};
@@ -72,7 +73,7 @@ impl FromLua for String {
7273
lua.coerce_string(value)?
7374
.ok_or_else(|| Error::FromLuaConversionError {
7475
from: ty,
75-
to: "string",
76+
to: "string".to_string(),
7677
message: Some("expected string or number".to_string()),
7778
})
7879
}
@@ -116,7 +117,7 @@ impl FromLua for Table {
116117
Value::Table(table) => Ok(table),
117118
_ => Err(Error::FromLuaConversionError {
118119
from: value.type_name(),
119-
to: "table",
120+
to: "table".to_string(),
120121
message: None,
121122
}),
122123
}
@@ -150,7 +151,7 @@ impl FromLua for Function {
150151
Value::Function(table) => Ok(table),
151152
_ => Err(Error::FromLuaConversionError {
152153
from: value.type_name(),
153-
to: "function",
154+
to: "function".to_string(),
154155
message: None,
155156
}),
156157
}
@@ -184,7 +185,7 @@ impl FromLua for Thread {
184185
Value::Thread(t) => Ok(t),
185186
_ => Err(Error::FromLuaConversionError {
186187
from: value.type_name(),
187-
to: "thread",
188+
to: "thread".to_string(),
188189
message: None,
189190
}),
190191
}
@@ -218,7 +219,7 @@ impl FromLua for AnyUserData {
218219
Value::UserData(ud) => Ok(ud),
219220
_ => Err(Error::FromLuaConversionError {
220221
from: value.type_name(),
221-
to: "userdata",
222+
to: "userdata".to_string(),
222223
message: None,
223224
}),
224225
}
@@ -336,7 +337,7 @@ impl FromLua for LightUserData {
336337
Value::LightUserData(ud) => Ok(ud),
337338
_ => Err(Error::FromLuaConversionError {
338339
from: value.type_name(),
339-
to: "light userdata",
340+
to: "lightuserdata".to_string(),
340341
message: None,
341342
}),
342343
}
@@ -359,7 +360,7 @@ impl FromLua for crate::types::Vector {
359360
Value::Vector(v) => Ok(v),
360361
_ => Err(Error::FromLuaConversionError {
361362
from: value.type_name(),
362-
to: "vector",
363+
to: "vector".to_string(),
363364
message: None,
364365
}),
365366
}
@@ -386,7 +387,7 @@ impl FromLua for StdString {
386387
.coerce_string(value)?
387388
.ok_or_else(|| Error::FromLuaConversionError {
388389
from: ty,
389-
to: "String",
390+
to: Self::type_name(),
390391
message: Some("expected string or number".to_string()),
391392
})?
392393
.to_str()?
@@ -405,7 +406,7 @@ impl FromLua for StdString {
405406
.map(|s| s.to_owned())
406407
.map_err(|e| Error::FromLuaConversionError {
407408
from: "string",
408-
to: "String",
409+
to: Self::type_name(),
409410
message: Some(e.to_string()),
410411
});
411412
}
@@ -448,7 +449,7 @@ impl FromLua for Box<str> {
448449
.coerce_string(value)?
449450
.ok_or_else(|| Error::FromLuaConversionError {
450451
from: ty,
451-
to: "Box<str>",
452+
to: Self::type_name(),
452453
message: Some("expected string or number".to_string()),
453454
})?
454455
.to_str()?
@@ -472,15 +473,15 @@ impl FromLua for CString {
472473
.coerce_string(value)?
473474
.ok_or_else(|| Error::FromLuaConversionError {
474475
from: ty,
475-
to: "CString",
476+
to: Self::type_name(),
476477
message: Some("expected string or number".to_string()),
477478
})?;
478479

479480
match CStr::from_bytes_with_nul(&string.as_bytes_with_nul()) {
480481
Ok(s) => Ok(s.into()),
481482
Err(_) => Err(Error::FromLuaConversionError {
482483
from: ty,
483-
to: "CString",
484+
to: Self::type_name(),
484485
message: Some("invalid C-style string".to_string()),
485486
}),
486487
}
@@ -525,7 +526,7 @@ impl FromLua for BString {
525526
.coerce_string(value)?
526527
.ok_or_else(|| Error::FromLuaConversionError {
527528
from: ty,
528-
to: "BString",
529+
to: Self::type_name(),
529530
message: Some("expected string or number".to_string()),
530531
})?
531532
.as_bytes())
@@ -588,7 +589,7 @@ macro_rules! lua_convert_int {
588589
.or_else(|| cast(self).map(Value::Number))
589590
// This is impossible error because conversion to Number never fails
590591
.ok_or_else(|| Error::ToLuaConversionError {
591-
from: stringify!($x),
592+
from: stringify!($x).to_string(),
592593
to: "number",
593594
message: Some("out of range".to_owned()),
594595
})
@@ -619,7 +620,7 @@ macro_rules! lua_convert_int {
619620
lua.coerce_number(value)?
620621
.ok_or_else(|| Error::FromLuaConversionError {
621622
from: ty,
622-
to: stringify!($x),
623+
to: stringify!($x).to_string(),
623624
message: Some(
624625
"expected number or string coercible to number".to_string(),
625626
),
@@ -630,7 +631,7 @@ macro_rules! lua_convert_int {
630631
})
631632
.ok_or_else(|| Error::FromLuaConversionError {
632633
from: ty,
633-
to: stringify!($x),
634+
to: stringify!($x).to_string(),
634635
message: Some("out of range".to_owned()),
635636
})
636637
}
@@ -644,7 +645,7 @@ macro_rules! lua_convert_int {
644645
if ok != 0 {
645646
return cast(i).ok_or_else(|| Error::FromLuaConversionError {
646647
from: "integer",
647-
to: stringify!($x),
648+
to: stringify!($x).to_string(),
648649
message: Some("out of range".to_owned()),
649650
});
650651
}
@@ -676,7 +677,7 @@ macro_rules! lua_convert_float {
676677
fn into_lua(self, _: &Lua) -> Result<Value> {
677678
cast(self)
678679
.ok_or_else(|| Error::ToLuaConversionError {
679-
from: stringify!($x),
680+
from: stringify!($x).to_string(),
680681
to: "number",
681682
message: Some("out of range".to_string()),
682683
})
@@ -691,13 +692,13 @@ macro_rules! lua_convert_float {
691692
lua.coerce_number(value)?
692693
.ok_or_else(|| Error::FromLuaConversionError {
693694
from: ty,
694-
to: stringify!($x),
695+
to: stringify!($x).to_string(),
695696
message: Some("expected number or string coercible to number".to_string()),
696697
})
697698
.and_then(|n| {
698699
cast(n).ok_or_else(|| Error::FromLuaConversionError {
699700
from: ty,
700-
to: stringify!($x),
701+
to: stringify!($x).to_string(),
701702
message: Some("number out of range".to_string()),
702703
})
703704
})
@@ -712,7 +713,7 @@ macro_rules! lua_convert_float {
712713
if ok != 0 {
713714
return cast(i).ok_or_else(|| Error::FromLuaConversionError {
714715
from: "number",
715-
to: stringify!($x),
716+
to: stringify!($x).to_string(),
716717
message: Some("out of range".to_owned()),
717718
});
718719
}
@@ -771,13 +772,13 @@ where
771772
vec.try_into()
772773
.map_err(|vec: Vec<T>| Error::FromLuaConversionError {
773774
from: "table",
774-
to: "Array",
775-
message: Some(format!("expected table of length {}, got {}", N, vec.len())),
775+
to: Self::type_name(),
776+
message: Some(format!("expected table of length {N}, got {}", vec.len())),
776777
})
777778
}
778779
_ => Err(Error::FromLuaConversionError {
779780
from: value.type_name(),
780-
to: "Array",
781+
to: Self::type_name(),
781782
message: Some("expected table".to_string()),
782783
}),
783784
}
@@ -812,7 +813,7 @@ impl<T: FromLua> FromLua for Vec<T> {
812813
Value::Table(table) => table.sequence_values().collect(),
813814
_ => Err(Error::FromLuaConversionError {
814815
from: value.type_name(),
815-
to: "Vec",
816+
to: Self::type_name(),
816817
message: Some("expected table".to_string()),
817818
}),
818819
}
@@ -834,7 +835,7 @@ impl<K: Eq + Hash + FromLua, V: FromLua, S: BuildHasher + Default> FromLua for H
834835
} else {
835836
Err(Error::FromLuaConversionError {
836837
from: value.type_name(),
837-
to: "HashMap",
838+
to: Self::type_name(),
838839
message: Some("expected table".to_string()),
839840
})
840841
}
@@ -856,7 +857,7 @@ impl<K: Ord + FromLua, V: FromLua> FromLua for BTreeMap<K, V> {
856857
} else {
857858
Err(Error::FromLuaConversionError {
858859
from: value.type_name(),
859-
to: "BTreeMap",
860+
to: Self::type_name(),
860861
message: Some("expected table".to_string()),
861862
})
862863
}
@@ -880,7 +881,7 @@ impl<T: Eq + Hash + FromLua, S: BuildHasher + Default> FromLua for HashSet<T, S>
880881
Value::Table(table) => table.pairs::<T, Value>().map(|res| res.map(|(k, _)| k)).collect(),
881882
_ => Err(Error::FromLuaConversionError {
882883
from: value.type_name(),
883-
to: "HashSet",
884+
to: Self::type_name(),
884885
message: Some("expected table".to_string()),
885886
}),
886887
}
@@ -904,7 +905,7 @@ impl<T: Ord + FromLua> FromLua for BTreeSet<T> {
904905
Value::Table(table) => table.pairs::<T, Value>().map(|res| res.map(|(k, _)| k)).collect(),
905906
_ => Err(Error::FromLuaConversionError {
906907
from: value.type_name(),
907-
to: "BTreeSet",
908+
to: Self::type_name(),
908909
message: Some("expected table".to_string()),
909910
}),
910911
}

src/error.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ pub enum Error {
8383
/// A Rust value could not be converted to a Lua value.
8484
ToLuaConversionError {
8585
/// Name of the Rust type that could not be converted.
86-
from: &'static str,
86+
from: String,
8787
/// Name of the Lua type that could not be created.
8888
to: &'static str,
8989
/// A message indicating why the conversion failed in more detail.
@@ -94,7 +94,7 @@ pub enum Error {
9494
/// Name of the Lua type that could not be converted.
9595
from: &'static str,
9696
/// Name of the Rust type that could not be created.
97-
to: &'static str,
97+
to: String,
9898
/// A string containing more detailed error information.
9999
message: Option<StdString>,
100100
},
@@ -384,12 +384,12 @@ impl Error {
384384

385385
pub(crate) fn from_lua_conversion(
386386
from: &'static str,
387-
to: &'static str,
387+
to: impl ToString,
388388
message: impl Into<Option<String>>,
389389
) -> Self {
390390
Error::FromLuaConversionError {
391391
from,
392-
to,
392+
to: to.to_string(),
393393
message: message.into(),
394394
}
395395
}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ pub use crate::table::{Table, TablePairs, TableSequence};
117117
pub use crate::thread::{Thread, ThreadStatus};
118118
pub use crate::traits::{LuaNativeFn, LuaNativeFnMut, ObjectLike};
119119
pub use crate::types::{
120-
AppDataRef, AppDataRefMut, Integer, LightUserData, MaybeSend, Number, RegistryKey, VmState,
120+
AppDataRef, AppDataRefMut, Either, Integer, LightUserData, MaybeSend, Number, RegistryKey, VmState,
121121
};
122122
pub use crate::userdata::{
123123
AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMetatable, UserDataMethods, UserDataRef,

src/prelude.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
33
#[doc(no_inline)]
44
pub use crate::{
5-
AnyUserData as LuaAnyUserData, Chunk as LuaChunk, Error as LuaError, ErrorContext as LuaErrorContext,
6-
ExternalError as LuaExternalError, ExternalResult as LuaExternalResult, FromLua, FromLuaMulti,
7-
Function as LuaFunction, FunctionInfo as LuaFunctionInfo, GCMode as LuaGCMode, Integer as LuaInteger,
8-
IntoLua, IntoLuaMulti, LightUserData as LuaLightUserData, Lua, LuaNativeFn, LuaNativeFnMut, LuaOptions,
9-
MetaMethod as LuaMetaMethod, MultiValue as LuaMultiValue, Nil as LuaNil, Number as LuaNumber,
10-
ObjectLike as LuaObjectLike, RegistryKey as LuaRegistryKey, Result as LuaResult, StdLib as LuaStdLib,
11-
String as LuaString, Table as LuaTable, TablePairs as LuaTablePairs, TableSequence as LuaTableSequence,
12-
Thread as LuaThread, ThreadStatus as LuaThreadStatus, UserData as LuaUserData,
13-
UserDataFields as LuaUserDataFields, UserDataMetatable as LuaUserDataMetatable,
5+
AnyUserData as LuaAnyUserData, Chunk as LuaChunk, Either as LuaEither, Error as LuaError,
6+
ErrorContext as LuaErrorContext, ExternalError as LuaExternalError, ExternalResult as LuaExternalResult,
7+
FromLua, FromLuaMulti, Function as LuaFunction, FunctionInfo as LuaFunctionInfo, GCMode as LuaGCMode,
8+
Integer as LuaInteger, IntoLua, IntoLuaMulti, LightUserData as LuaLightUserData, Lua, LuaNativeFn,
9+
LuaNativeFnMut, LuaOptions, MetaMethod as LuaMetaMethod, MultiValue as LuaMultiValue, Nil as LuaNil,
10+
Number as LuaNumber, ObjectLike as LuaObjectLike, RegistryKey as LuaRegistryKey, Result as LuaResult,
11+
StdLib as LuaStdLib, String as LuaString, Table as LuaTable, TablePairs as LuaTablePairs,
12+
TableSequence as LuaTableSequence, Thread as LuaThread, ThreadStatus as LuaThreadStatus,
13+
UserData as LuaUserData, UserDataFields as LuaUserDataFields, UserDataMetatable as LuaUserDataMetatable,
1414
UserDataMethods as LuaUserDataMethods, UserDataRef as LuaUserDataRef,
1515
UserDataRefMut as LuaUserDataRefMut, UserDataRegistry as LuaUserDataRegistry, Value as LuaValue,
1616
VmState as LuaVmState,

src/string.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl String {
4545
let BorrowedBytes(bytes, guard) = self.as_bytes();
4646
let s = str::from_utf8(bytes).map_err(|e| Error::FromLuaConversionError {
4747
from: "string",
48-
to: "&str",
48+
to: "&str".to_string(),
4949
message: Some(e.to_string()),
5050
})?;
5151
Ok(BorrowedStr(s, guard))

src/traits.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,21 @@ use std::string::String as StdString;
33
use crate::error::Result;
44
use crate::private::Sealed;
55
use crate::types::MaybeSend;
6+
use crate::util::short_type_name;
67
use crate::value::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti};
78

89
#[cfg(feature = "async")]
910
use std::future::Future;
1011

12+
pub(crate) trait ShortTypeName {
13+
#[inline(always)]
14+
fn type_name() -> StdString {
15+
short_type_name::<Self>()
16+
}
17+
}
18+
19+
impl<T> ShortTypeName for T {}
20+
1121
/// A trait for types that can be used as Lua objects (usually table and userdata).
1222
pub trait ObjectLike: Sealed {
1323
/// Gets the value associated to `key` from the object, assuming it has `__index` metamethod.

src/types.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub(crate) type BoxFuture<'a, T> = futures_util::future::BoxFuture<'a, T>;
1717
pub(crate) type BoxFuture<'a, T> = futures_util::future::LocalBoxFuture<'a, T>;
1818

1919
pub use app_data::{AppData, AppDataRef, AppDataRefMut};
20+
pub use either::Either;
2021
pub use registry_key::RegistryKey;
2122
pub(crate) use value_ref::ValueRef;
2223
#[cfg(any(feature = "luau", doc))]
@@ -132,6 +133,7 @@ impl LuaType for LightUserData {
132133
}
133134

134135
mod app_data;
136+
mod either;
135137
mod registry_key;
136138
mod sync;
137139
mod value_ref;

0 commit comments

Comments
 (0)