Skip to content

Commit 17c5cd3

Browse files
committed
Replace BytesBox with LuaBytes wrapper around bytes::Bytes
1 parent 14d9b01 commit 17c5cd3

File tree

1 file changed

+47
-19
lines changed

1 file changed

+47
-19
lines changed

src/bytes.rs

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,80 @@
1-
use std::ops::Deref;
1+
use std::ops::{Deref, DerefMut};
22

3+
use bytes::Bytes;
34
use mlua::{
4-
BorrowedBytes, Error, FromLua, Lua, MaybeSend, Result, String as LuaString, UserData, UserDataRef, Value,
5+
BorrowedBytes, Error, FromLua, Lua, MetaMethod, Result, String as LuaString, UserData, UserDataMethods,
6+
UserDataRegistry, Value,
57
};
68

7-
/// A wrapper around a byte slice that can be passed to Lua as userdata.
8-
#[cfg(not(feature = "send"))]
9-
pub struct BytesBox(Box<dyn AsRef<[u8]>>);
9+
/// A Lua userdata wrapper around [`Bytes`].
10+
#[derive(Clone, Default, Debug, FromLua, PartialEq, Eq, Hash, Ord, PartialOrd)]
11+
pub struct LuaBytes(pub Bytes);
1012

11-
/// A wrapper around a byte slice that can be passed to Lua as userdata.
12-
#[cfg(feature = "send")]
13-
pub struct BytesBox(Box<dyn AsRef<[u8]> + Send>);
13+
impl Deref for LuaBytes {
14+
type Target = Bytes;
1415

15-
impl<T: AsRef<[u8]> + MaybeSend + 'static> From<T> for BytesBox {
16-
#[inline(always)]
17-
fn from(value: T) -> Self {
18-
Self(Box::new(value))
16+
#[inline]
17+
fn deref(&self) -> &Self::Target {
18+
&self.0
19+
}
20+
}
21+
22+
impl DerefMut for LuaBytes {
23+
#[inline]
24+
fn deref_mut(&mut self) -> &mut Self::Target {
25+
&mut self.0
1926
}
2027
}
2128

22-
impl UserData for BytesBox {}
29+
impl UserData for LuaBytes {
30+
fn register(registry: &mut UserDataRegistry<Self>) {
31+
registry.add_method("len", |_, this, ()| Ok(this.len()));
32+
33+
registry.add_method("is_empty", |_, this, ()| Ok(this.is_empty()));
34+
35+
registry.add_method_mut("split_off", |_, this, n| Ok(Self(this.split_off(n))));
36+
registry.add_method_mut("split_to", |_, this, n| Ok(Self(this.split_to(n))));
37+
38+
registry.add_method_mut("clear", |_, this, ()| {
39+
this.clear();
40+
Ok(())
41+
});
42+
registry.add_method_mut("truncate", |_, this, len| {
43+
this.truncate(len);
44+
Ok(())
45+
});
46+
47+
registry.add_meta_method(MetaMethod::ToString, |lua, this, ()| lua.create_string(&this.0));
48+
}
49+
}
2350

24-
/// A type that can represent either a Lua string or a `BytesBox` userdata.
51+
/// A type that can represent either a Lua string or a [`LuaBytes`] userdata.
2552
pub enum StringOrBytes {
2653
String(LuaString),
27-
Bytes(UserDataRef<BytesBox>),
54+
Bytes(LuaBytes),
2855
}
2956

3057
impl FromLua for StringOrBytes {
3158
fn from_lua(value: Value, _lua: &Lua) -> Result<Self> {
3259
match value {
3360
Value::String(s) => Ok(Self::String(s)),
34-
Value::UserData(ud) => Ok(Self::Bytes(ud.borrow::<BytesBox>()?)),
61+
Value::UserData(ud) => Ok(Self::Bytes(ud.borrow::<LuaBytes>()?.clone())),
3562
_ => Err(Error::FromLuaConversionError {
3663
from: value.type_name(),
37-
to: "string or bytes".into(),
64+
to: "String or Bytes".into(),
3865
message: None,
3966
}),
4067
}
4168
}
4269
}
4370

4471
impl StringOrBytes {
72+
/// Get a type that dereferences to a underlying byte slice.
4573
#[inline]
46-
pub(crate) fn as_bytes_deref(&self) -> impl Deref<Target = [u8]> {
74+
pub fn as_bytes_deref(&self) -> impl Deref<Target = [u8]> {
4775
match self {
4876
StringOrBytes::String(s) => AsBytesRefImpl::Lua(s.as_bytes()),
49-
StringOrBytes::Bytes(b) => AsBytesRefImpl::Ref((*b.0).as_ref()),
77+
StringOrBytes::Bytes(b) => AsBytesRefImpl::Ref(b.as_ref()),
5078
}
5179
}
5280
}

0 commit comments

Comments
 (0)