1010//! - [`BorrowedBytes`] - A borrowed `&[u8]` view of a Lua string that holds a strong reference to
1111//! the Lua state.
1212
13- use std:: borrow:: { Borrow , Cow } ;
13+ use std:: borrow:: Borrow ;
1414use std:: hash:: { Hash , Hasher } ;
1515use std:: ops:: Deref ;
1616use std:: os:: raw:: { c_int, c_void} ;
17- use std:: { cmp, fmt, slice, str} ;
17+ use std:: { cmp, fmt, mem , slice, str} ;
1818
1919use crate :: error:: { Error , Result } ;
2020use crate :: state:: Lua ;
@@ -37,6 +37,9 @@ pub struct LuaString(pub(crate) ValueRef);
3737impl LuaString {
3838 /// Get a [`BorrowedStr`] if the Lua string is valid UTF-8.
3939 ///
40+ /// The returned `BorrowedStr` holds a strong reference to the Lua state to guarantee the
41+ /// validity of the underlying data.
42+ ///
4043 /// # Examples
4144 ///
4245 /// ```
@@ -54,7 +57,7 @@ impl LuaString {
5457 /// # }
5558 /// ```
5659 #[ inline]
57- pub fn to_str ( & self ) -> Result < BorrowedStr < ' _ > > {
60+ pub fn to_str ( & self ) -> Result < BorrowedStr > {
5861 BorrowedStr :: try_from ( self )
5962 }
6063
@@ -97,8 +100,9 @@ impl LuaString {
97100
98101 /// Get the bytes that make up this string.
99102 ///
100- /// The returned slice will not contain the terminating null byte, but will contain any null
101- /// bytes embedded into the Lua string.
103+ /// The returned `BorrowedStr` holds a strong reference to the Lua state to guarantee the
104+ /// validity of the underlying data. The data will not contain the terminating null byte, but
105+ /// will contain any null bytes embedded into the Lua string.
102106 ///
103107 /// # Examples
104108 ///
@@ -113,16 +117,16 @@ impl LuaString {
113117 /// # }
114118 /// ```
115119 #[ inline]
116- pub fn as_bytes ( & self ) -> BorrowedBytes < ' _ > {
120+ pub fn as_bytes ( & self ) -> BorrowedBytes {
117121 BorrowedBytes :: from ( self )
118122 }
119123
120124 /// Get the bytes that make up this string, including the trailing null byte.
121- pub fn as_bytes_with_nul ( & self ) -> BorrowedBytes < ' _ > {
122- let BorrowedBytes { buf, borrow , _lua } = BorrowedBytes :: from ( self ) ;
125+ pub fn as_bytes_with_nul ( & self ) -> BorrowedBytes {
126+ let BorrowedBytes { buf, vref , _lua } = BorrowedBytes :: from ( self ) ;
123127 // Include the trailing null byte (it's always present but excluded by default)
124128 let buf = unsafe { slice:: from_raw_parts ( ( * buf) . as_ptr ( ) , ( * buf) . len ( ) + 1 ) } ;
125- BorrowedBytes { buf, borrow , _lua }
129+ BorrowedBytes { buf, vref , _lua }
126130 }
127131
128132 // Does not return the terminating null byte
@@ -245,14 +249,14 @@ impl fmt::Display for Display<'_> {
245249}
246250
247251/// A borrowed string (`&str`) that holds a strong reference to the Lua state.
248- pub struct BorrowedStr < ' a > {
252+ pub struct BorrowedStr {
249253 // `buf` points to a readonly memory managed by Lua
250- pub ( crate ) buf : & ' a str ,
251- pub ( crate ) borrow : Cow < ' a , LuaString > ,
254+ pub ( crate ) buf : & ' static str ,
255+ pub ( crate ) vref : ValueRef ,
252256 pub ( crate ) _lua : Lua ,
253257}
254258
255- impl Deref for BorrowedStr < ' _ > {
259+ impl Deref for BorrowedStr {
256260 type Target = str ;
257261
258262 #[ inline( always) ]
@@ -261,33 +265,33 @@ impl Deref for BorrowedStr<'_> {
261265 }
262266}
263267
264- impl Borrow < str > for BorrowedStr < ' _ > {
268+ impl Borrow < str > for BorrowedStr {
265269 #[ inline( always) ]
266270 fn borrow ( & self ) -> & str {
267271 self . buf
268272 }
269273}
270274
271- impl AsRef < str > for BorrowedStr < ' _ > {
275+ impl AsRef < str > for BorrowedStr {
272276 #[ inline( always) ]
273277 fn as_ref ( & self ) -> & str {
274278 self . buf
275279 }
276280}
277281
278- impl fmt:: Display for BorrowedStr < ' _ > {
282+ impl fmt:: Display for BorrowedStr {
279283 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
280284 self . buf . fmt ( f)
281285 }
282286}
283287
284- impl fmt:: Debug for BorrowedStr < ' _ > {
288+ impl fmt:: Debug for BorrowedStr {
285289 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
286290 self . buf . fmt ( f)
287291 }
288292}
289293
290- impl < T > PartialEq < T > for BorrowedStr < ' _ >
294+ impl < T > PartialEq < T > for BorrowedStr
291295where
292296 T : AsRef < str > ,
293297{
@@ -296,9 +300,9 @@ where
296300 }
297301}
298302
299- impl Eq for BorrowedStr < ' _ > { }
303+ impl Eq for BorrowedStr { }
300304
301- impl < T > PartialOrd < T > for BorrowedStr < ' _ >
305+ impl < T > PartialOrd < T > for BorrowedStr
302306where
303307 T : AsRef < str > ,
304308{
@@ -307,33 +311,33 @@ where
307311 }
308312}
309313
310- impl Ord for BorrowedStr < ' _ > {
314+ impl Ord for BorrowedStr {
311315 fn cmp ( & self , other : & Self ) -> cmp:: Ordering {
312316 self . buf . cmp ( other. buf )
313317 }
314318}
315319
316- impl < ' a > TryFrom < & ' a LuaString > for BorrowedStr < ' a > {
320+ impl TryFrom < & LuaString > for BorrowedStr {
317321 type Error = Error ;
318322
319323 #[ inline]
320- fn try_from ( value : & ' a LuaString ) -> Result < Self > {
321- let BorrowedBytes { buf, borrow , _lua } = BorrowedBytes :: from ( value) ;
324+ fn try_from ( value : & LuaString ) -> Result < Self > {
325+ let BorrowedBytes { buf, vref , _lua } = BorrowedBytes :: from ( value) ;
322326 let buf =
323327 str:: from_utf8 ( buf) . map_err ( |e| Error :: from_lua_conversion ( "string" , "&str" , e. to_string ( ) ) ) ?;
324- Ok ( Self { buf, borrow , _lua } )
328+ Ok ( Self { buf, vref , _lua } )
325329 }
326330}
327331
328332/// A borrowed byte slice (`&[u8]`) that holds a strong reference to the Lua state.
329- pub struct BorrowedBytes < ' a > {
333+ pub struct BorrowedBytes {
330334 // `buf` points to a readonly memory managed by Lua
331- pub ( crate ) buf : & ' a [ u8 ] ,
332- pub ( crate ) borrow : Cow < ' a , LuaString > ,
335+ pub ( crate ) buf : & ' static [ u8 ] ,
336+ pub ( crate ) vref : ValueRef ,
333337 pub ( crate ) _lua : Lua ,
334338}
335339
336- impl Deref for BorrowedBytes < ' _ > {
340+ impl Deref for BorrowedBytes {
337341 type Target = [ u8 ] ;
338342
339343 #[ inline( always) ]
@@ -342,27 +346,27 @@ impl Deref for BorrowedBytes<'_> {
342346 }
343347}
344348
345- impl Borrow < [ u8 ] > for BorrowedBytes < ' _ > {
349+ impl Borrow < [ u8 ] > for BorrowedBytes {
346350 #[ inline( always) ]
347351 fn borrow ( & self ) -> & [ u8 ] {
348352 self . buf
349353 }
350354}
351355
352- impl AsRef < [ u8 ] > for BorrowedBytes < ' _ > {
356+ impl AsRef < [ u8 ] > for BorrowedBytes {
353357 #[ inline( always) ]
354358 fn as_ref ( & self ) -> & [ u8 ] {
355359 self . buf
356360 }
357361}
358362
359- impl fmt:: Debug for BorrowedBytes < ' _ > {
363+ impl fmt:: Debug for BorrowedBytes {
360364 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
361365 self . buf . fmt ( f)
362366 }
363367}
364368
365- impl < T > PartialEq < T > for BorrowedBytes < ' _ >
369+ impl < T > PartialEq < T > for BorrowedBytes
366370where
367371 T : AsRef < [ u8 ] > ,
368372{
@@ -371,9 +375,9 @@ where
371375 }
372376}
373377
374- impl Eq for BorrowedBytes < ' _ > { }
378+ impl Eq for BorrowedBytes { }
375379
376- impl < T > PartialOrd < T > for BorrowedBytes < ' _ >
380+ impl < T > PartialOrd < T > for BorrowedBytes
377381where
378382 T : AsRef < [ u8 ] > ,
379383{
@@ -382,13 +386,13 @@ where
382386 }
383387}
384388
385- impl Ord for BorrowedBytes < ' _ > {
389+ impl Ord for BorrowedBytes {
386390 fn cmp ( & self , other : & Self ) -> cmp:: Ordering {
387391 self . buf . cmp ( other. buf )
388392 }
389393}
390394
391- impl < ' a > IntoIterator for & ' a BorrowedBytes < ' _ > {
395+ impl < ' a > IntoIterator for & ' a BorrowedBytes {
392396 type Item = & ' a u8 ;
393397 type IntoIter = slice:: Iter < ' a , u8 > ;
394398
@@ -397,12 +401,14 @@ impl<'a> IntoIterator for &'a BorrowedBytes<'_> {
397401 }
398402}
399403
400- impl < ' a > From < & ' a LuaString > for BorrowedBytes < ' a > {
404+ impl From < & LuaString > for BorrowedBytes {
401405 #[ inline]
402- fn from ( value : & ' a LuaString ) -> Self {
406+ fn from ( value : & LuaString ) -> Self {
403407 let ( buf, _lua) = unsafe { value. to_slice ( ) } ;
404- let borrow = Cow :: Borrowed ( value) ;
405- Self { buf, borrow, _lua }
408+ let vref = value. 0 . clone ( ) ;
409+ // SAFETY: The `buf` is valid for the lifetime of the Lua state and occupied slot index
410+ let buf = unsafe { mem:: transmute :: < & [ u8 ] , & ' static [ u8 ] > ( buf) } ;
411+ Self { buf, vref, _lua }
406412 }
407413}
408414
0 commit comments