summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Orlenko <zxteam@protonmail.com>2022-12-19 14:59:21 +0000
committerAlex Orlenko <zxteam@protonmail.com>2022-12-19 21:12:36 +0000
commit56abc4a700b246dcd4b6c0b0a818779577067cc2 (patch)
treec3583a386411a98d94d3b3f9b080d71370b355f9 /src
parent9b4e3a1598bd95908b33c0a4052fa9563523cee6 (diff)
downloadmlua-56abc4a700b246dcd4b6c0b0a818779577067cc2.zip
Refactor `AsChunk` trait
Diffstat (limited to 'src')
-rw-r--r--src/chunk.rs101
-rw-r--r--src/function.rs2
-rw-r--r--src/lua.rs21
-rw-r--r--src/luau.rs2
4 files changed, 62 insertions, 64 deletions
diff --git a/src/chunk.rs b/src/chunk.rs
index bd24ae4..0315ef9 100644
--- a/src/chunk.rs
+++ b/src/chunk.rs
@@ -18,10 +18,7 @@ use {futures_core::future::LocalBoxFuture, futures_util::future};
///
/// [loadable by Lua]: https://www.lua.org/manual/5.4/manual.html#3.3.2
/// [`Chunk`]: crate::Chunk
-pub trait AsChunk<'lua> {
- /// Returns chunk data (can be text or binary)
- fn source(&self) -> IoResult<Cow<[u8]>>;
-
+pub trait AsChunk<'a> {
/// Returns optional chunk name
fn name(&self) -> Option<StdString> {
None
@@ -30,58 +27,74 @@ pub trait AsChunk<'lua> {
/// Returns optional chunk [environment]
///
/// [environment]: https://www.lua.org/manual/5.4/manual.html#2.2
- fn env(&self, _lua: &'lua Lua) -> Result<Option<Value<'lua>>> {
- Ok(None)
+ fn env<'lua>(&self, lua: &'lua Lua) -> Result<Value<'lua>> {
+ let _lua = lua; // suppress warning
+ Ok(Value::Nil)
}
/// Returns optional chunk mode (text or binary)
fn mode(&self) -> Option<ChunkMode> {
None
}
+
+ /// Returns chunk data (can be text or binary)
+ fn source(self) -> IoResult<Cow<'a, [u8]>>;
}
-impl<'lua> AsChunk<'lua> for str {
- fn source(&self) -> IoResult<Cow<[u8]>> {
+impl<'a> AsChunk<'a> for &'a str {
+ fn source(self) -> IoResult<Cow<'a, [u8]>> {
Ok(Cow::Borrowed(self.as_ref()))
}
}
-impl<'lua> AsChunk<'lua> for StdString {
- fn source(&self) -> IoResult<Cow<[u8]>> {
- Ok(Cow::Borrowed(self.as_ref()))
+impl AsChunk<'static> for StdString {
+ fn source(self) -> IoResult<Cow<'static, [u8]>> {
+ Ok(Cow::Owned(self.into_bytes()))
}
}
-impl<'lua> AsChunk<'lua> for [u8] {
- fn source(&self) -> IoResult<Cow<[u8]>> {
- Ok(Cow::Borrowed(self))
+impl<'a> AsChunk<'a> for &'a StdString {
+ fn source(self) -> IoResult<Cow<'a, [u8]>> {
+ Ok(Cow::Borrowed(self.as_bytes()))
}
}
-impl<'lua> AsChunk<'lua> for Vec<u8> {
- fn source(&self) -> IoResult<Cow<[u8]>> {
+impl<'a> AsChunk<'a> for &'a [u8] {
+ fn source(self) -> IoResult<Cow<'a, [u8]>> {
Ok(Cow::Borrowed(self))
}
}
-impl<'lua> AsChunk<'lua> for Path {
- fn source(&self) -> IoResult<Cow<[u8]>> {
- std::fs::read(self).map(Cow::Owned)
+impl AsChunk<'static> for Vec<u8> {
+ fn source(self) -> IoResult<Cow<'static, [u8]>> {
+ Ok(Cow::Owned(self))
+ }
+}
+
+impl<'a> AsChunk<'a> for &'a Vec<u8> {
+ fn source(self) -> IoResult<Cow<'a, [u8]>> {
+ Ok(Cow::Borrowed(self.as_ref()))
}
+}
+impl AsChunk<'static> for &Path {
fn name(&self) -> Option<StdString> {
Some(format!("@{}", self.display()))
}
-}
-impl<'lua> AsChunk<'lua> for PathBuf {
- fn source(&self) -> IoResult<Cow<[u8]>> {
+ fn source(self) -> IoResult<Cow<'static, [u8]>> {
std::fs::read(self).map(Cow::Owned)
}
+}
+impl AsChunk<'static> for PathBuf {
fn name(&self) -> Option<StdString> {
Some(format!("@{}", self.display()))
}
+
+ fn source(self) -> IoResult<Cow<'static, [u8]>> {
+ std::fs::read(self).map(Cow::Owned)
+ }
}
/// Returned from [`Lua::load`] and is used to finalize loading and executing Lua main chunks.
@@ -90,10 +103,10 @@ impl<'lua> AsChunk<'lua> for PathBuf {
#[must_use = "`Chunk`s do nothing unless one of `exec`, `eval`, `call`, or `into_function` are called on them"]
pub struct Chunk<'lua, 'a> {
pub(crate) lua: &'lua Lua,
- pub(crate) source: IoResult<Cow<'a, [u8]>>,
- pub(crate) name: Option<StdString>,
- pub(crate) env: Result<Option<Value<'lua>>>,
+ pub(crate) name: StdString,
+ pub(crate) env: Result<Value<'lua>>,
pub(crate) mode: Option<ChunkMode>,
+ pub(crate) source: IoResult<Cow<'a, [u8]>>,
#[cfg(feature = "luau")]
pub(crate) compiler: Option<Compiler>,
}
@@ -237,11 +250,9 @@ impl Compiler {
impl<'lua, 'a> Chunk<'lua, 'a> {
/// Sets the name of this chunk, which results in more informative error traces.
- pub fn set_name(mut self, name: impl AsRef<str>) -> Result<Self> {
- self.name = Some(name.as_ref().to_string());
- // Do extra validation
- let _ = self.convert_name()?;
- Ok(self)
+ pub fn set_name(mut self, name: impl Into<String>) -> Self {
+ self.name = name.into();
+ self
}
/// Sets the first upvalue (`_ENV`) of the loaded chunk to the given value.
@@ -255,10 +266,9 @@ impl<'lua, 'a> Chunk<'lua, 'a> {
/// All global variables (including the standard library!) are looked up in `_ENV`, so it may be
/// necessary to populate the environment in order for scripts using custom environments to be
/// useful.
- pub fn set_environment<V: ToLua<'lua>>(mut self, env: V) -> Result<Self> {
- // Prefer to propagate errors here and wrap to `Ok`
- self.env = Ok(Some(env.to_lua(self.lua)?));
- Ok(self)
+ pub fn set_environment<V: ToLua<'lua>>(mut self, env: V) -> Self {
+ self.env = env.to_lua(self.lua);
+ self
}
/// Sets whether the chunk is text or binary (autodetected by default).
@@ -299,10 +309,7 @@ impl<'lua, 'a> Chunk<'lua, 'a> {
/// [`exec`]: #method.exec
#[cfg(feature = "async")]
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
- pub fn exec_async<'fut>(self) -> LocalBoxFuture<'fut, Result<()>>
- where
- 'lua: 'fut,
- {
+ pub fn exec_async(self) -> LocalBoxFuture<'lua, Result<()>> {
self.call_async(())
}
@@ -387,9 +394,9 @@ impl<'lua, 'a> Chunk<'lua, 'a> {
self.compile();
}
- let name = self.convert_name()?;
+ let name = Self::convert_name(self.name)?;
self.lua
- .load_chunk(self.source?.as_ref(), name.as_deref(), self.env?, self.mode)
+ .load_chunk(Some(&name), self.env?, self.mode, self.source?.as_ref())
}
/// Compiles the chunk and changes mode to binary.
@@ -408,7 +415,7 @@ impl<'lua, 'a> Chunk<'lua, 'a> {
self.mode = Some(ChunkMode::Binary);
}
#[cfg(not(feature = "luau"))]
- if let Ok(func) = self.lua.load_chunk(source.as_ref(), None, None, None) {
+ if let Ok(func) = self.lua.load_chunk(None, Value::Nil, None, source.as_ref()) {
let data = func.dump(false);
self.source = Ok(Cow::Owned(data));
self.mode = Some(ChunkMode::Binary);
@@ -470,9 +477,9 @@ impl<'lua, 'a> Chunk<'lua, 'a> {
.map(|c| c.compile(&source))
.unwrap_or(source);
- let name = self.convert_name()?;
+ let name = Self::convert_name(self.name.clone())?;
self.lua
- .load_chunk(&source, name.as_deref(), self.env.clone()?, None)
+ .load_chunk(Some(&name), self.env.clone()?, None, &source)
}
fn detect_mode(&self) -> ChunkMode {
@@ -493,12 +500,8 @@ impl<'lua, 'a> Chunk<'lua, 'a> {
}
}
- fn convert_name(&self) -> Result<Option<CString>> {
- self.name
- .clone()
- .map(CString::new)
- .transpose()
- .map_err(|err| Error::RuntimeError(format!("invalid name: {err}")))
+ fn convert_name(name: String) -> Result<CString> {
+ CString::new(name).map_err(|err| Error::RuntimeError(format!("invalid name: {err}")))
}
fn expression_source(source: &[u8]) -> Vec<u8> {
diff --git a/src/function.rs b/src/function.rs
index d5edda4..0581e92 100644
--- a/src/function.rs
+++ b/src/function.rs
@@ -255,7 +255,7 @@ impl<'lua> Function<'lua> {
"#,
)
.try_cache()
- .set_name("_mlua_bind")?
+ .set_name("_mlua_bind")
.call((self.clone(), args_wrapper))
}
diff --git a/src/lua.rs b/src/lua.rs
index 86473eb..e22b8d7 100644
--- a/src/lua.rs
+++ b/src/lua.rs
@@ -1348,19 +1348,14 @@ impl Lua {
///
/// [`Chunk::exec`]: crate::Chunk::exec
#[track_caller]
- pub fn load<'lua, 'a, S>(&'lua self, chunk: &'a S) -> Chunk<'lua, 'a>
- where
- S: AsChunk<'lua> + ?Sized,
- {
+ pub fn load<'lua, 'a>(&'lua self, chunk: impl AsChunk<'a>) -> Chunk<'lua, 'a> {
let caller = Location::caller();
- let name = chunk.name().unwrap_or_else(|| caller.to_string());
-
Chunk {
lua: self,
- source: chunk.source(),
- name: Some(name),
+ name: chunk.name().unwrap_or_else(|| caller.to_string()),
env: chunk.env(self),
mode: chunk.mode(),
+ source: chunk.source(),
#[cfg(feature = "luau")]
compiler: unsafe { (*self.extra.get()).compiler.clone() },
}
@@ -1368,10 +1363,10 @@ impl Lua {
pub(crate) fn load_chunk<'lua>(
&'lua self,
- source: &[u8],
name: Option<&CStr>,
- env: Option<Value<'lua>>,
+ env: Value<'lua>,
mode: Option<ChunkMode>,
+ source: &[u8],
) -> Result<Function<'lua>> {
let state = self.state();
unsafe {
@@ -1392,7 +1387,7 @@ impl Lua {
mode_str,
) {
ffi::LUA_OK => {
- if let Some(env) = env {
+ if env != Value::Nil {
self.push_value(env)?;
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
ffi::lua_setupvalue(state, -2, 1);
@@ -2885,8 +2880,8 @@ impl Lua {
"#,
)
.try_cache()
- .set_name("_mlua_async_poll")?
- .set_environment(env)?
+ .set_name("_mlua_async_poll")
+ .set_environment(env)
.into_function()
}
diff --git a/src/luau.rs b/src/luau.rs
index 7dab235..807a7f1 100644
--- a/src/luau.rs
+++ b/src/luau.rs
@@ -106,7 +106,7 @@ fn lua_require(lua: &Lua, name: Option<StdString>) -> Result<Value> {
let value = lua
.load(&source)
- .set_name(&format!("={}", source_name))?
+ .set_name(&format!("={}", source_name))
.set_mode(ChunkMode::Text)
.call::<_, Value>(())?;