1- use  std:: borrow:: Borrow ; 
1+ use  std:: borrow:: { Borrow ,   Cow } ; 
22use  std:: hash:: { Hash ,  Hasher } ; 
33use  std:: ops:: Deref ; 
44use  std:: os:: raw:: { c_int,  c_void} ; 
@@ -44,13 +44,7 @@ impl String {
4444/// ``` 
4545#[ inline]  
4646    pub  fn  to_str ( & self )  -> Result < BorrowedStr >  { 
47-         let  BorrowedBytes ( bytes,  guard)  = self . as_bytes ( ) ; 
48-         let  s = str:: from_utf8 ( bytes) . map_err ( |e| Error :: FromLuaConversionError  { 
49-             from :  "string" , 
50-             to :  "&str" . to_string ( ) , 
51-             message :  Some ( e. to_string ( ) ) , 
52-         } ) ?; 
53-         Ok ( BorrowedStr ( s,  guard) ) 
47+         BorrowedStr :: try_from ( self ) 
5448    } 
5549
5650    /// Converts this string to a [`StdString`]. 
@@ -109,19 +103,21 @@ impl String {
109103/// ``` 
110104#[ inline]  
111105    pub  fn  as_bytes ( & self )  -> BorrowedBytes  { 
112-         let  ( bytes,  guard)  = unsafe  {  self . to_slice ( )  } ; 
113-         BorrowedBytes ( & bytes[ ..bytes. len ( )  - 1 ] ,  guard) 
106+         BorrowedBytes :: from ( self ) 
114107    } 
115108
116109    /// Get the bytes that make up this string, including the trailing nul byte. 
117110pub  fn  as_bytes_with_nul ( & self )  -> BorrowedBytes  { 
118-         let  ( bytes,  guard)  = unsafe  {  self . to_slice ( )  } ; 
119-         BorrowedBytes ( bytes,  guard) 
111+         let  BorrowedBytes  {  buf,  borrow,  _lua }  = BorrowedBytes :: from ( self ) ; 
112+         // Include the trailing nul byte (it's always present but excluded by default) 
113+         let  buf = unsafe  {  slice:: from_raw_parts ( ( * buf) . as_ptr ( ) ,  ( * buf) . len ( )  + 1 )  } ; 
114+         BorrowedBytes  {  buf,  borrow,  _lua } 
120115    } 
121116
117+     // Does not return the terminating nul byte 
122118    unsafe  fn  to_slice ( & self )  -> ( & [ u8 ] ,  Lua )  { 
123119        let  lua = self . 0 . lua . upgrade ( ) ; 
124-         let  slice = unsafe   { 
120+         let  slice = { 
125121            let  rawlua = lua. lock ( ) ; 
126122            let  ref_thread = rawlua. ref_thread ( ) ; 
127123
@@ -134,7 +130,7 @@ impl String {
134130            // string type 
135131            let  mut  size = 0 ; 
136132            let  data = ffi:: lua_tolstring ( ref_thread,  self . 0 . index ,  & mut  size) ; 
137-             slice:: from_raw_parts ( data as  * const  u8 ,  size +  1 ) 
133+             slice:: from_raw_parts ( data as  * const  u8 ,  size) 
138134        } ; 
139135        ( slice,  lua) 
140136    } 
@@ -238,40 +234,45 @@ impl fmt::Display for Display<'_> {
238234} 
239235
240236/// A borrowed string (`&str`) that holds a strong reference to the Lua state. 
241- pub  struct  BorrowedStr < ' a > ( & ' a  str ,  #[ allow( unused) ]   Lua ) ; 
237+ pub  struct  BorrowedStr < ' a >  { 
238+     // `buf` points to a readonly memory managed by Lua 
239+     pub ( crate )  buf :  & ' a  str , 
240+     pub ( crate )  borrow :  Cow < ' a ,  String > , 
241+     pub ( crate )  _lua :  Lua , 
242+ } 
242243
243244impl  Deref  for  BorrowedStr < ' _ >  { 
244245    type  Target  = str ; 
245246
246247    #[ inline( always) ]  
247248    fn  deref ( & self )  -> & str  { 
248-         self . 0 
249+         self . buf 
249250    } 
250251} 
251252
252253impl  Borrow < str >  for  BorrowedStr < ' _ >  { 
253254    #[ inline( always) ]  
254255    fn  borrow ( & self )  -> & str  { 
255-         self . 0 
256+         self . buf 
256257    } 
257258} 
258259
259260impl  AsRef < str >  for  BorrowedStr < ' _ >  { 
260261    #[ inline( always) ]  
261262    fn  as_ref ( & self )  -> & str  { 
262-         self . 0 
263+         self . buf 
263264    } 
264265} 
265266
266267impl  fmt:: Display  for  BorrowedStr < ' _ >  { 
267268    fn  fmt ( & self ,  f :  & mut  fmt:: Formatter )  -> fmt:: Result  { 
268-         self . 0 . fmt ( f) 
269+         self . buf . fmt ( f) 
269270    } 
270271} 
271272
272273impl  fmt:: Debug  for  BorrowedStr < ' _ >  { 
273274    fn  fmt ( & self ,  f :  & mut  fmt:: Formatter )  -> fmt:: Result  { 
274-         self . 0 . fmt ( f) 
275+         self . buf . fmt ( f) 
275276    } 
276277} 
277278
@@ -280,7 +281,7 @@ where
280281    T :  AsRef < str > , 
281282{ 
282283    fn  eq ( & self ,  other :  & T )  -> bool  { 
283-         self . 0  == other. as_ref ( ) 
284+         self . buf  == other. as_ref ( ) 
284285    } 
285286} 
286287
@@ -291,45 +292,65 @@ where
291292    T :  AsRef < str > , 
292293{ 
293294    fn  partial_cmp ( & self ,  other :  & T )  -> Option < cmp:: Ordering >  { 
294-         self . 0 . partial_cmp ( other. as_ref ( ) ) 
295+         self . buf . partial_cmp ( other. as_ref ( ) ) 
295296    } 
296297} 
297298
298299impl  Ord  for  BorrowedStr < ' _ >  { 
299300    fn  cmp ( & self ,  other :  & Self )  -> cmp:: Ordering  { 
300-         self . 0 . cmp ( other. 0 ) 
301+         self . buf . cmp ( other. buf ) 
302+     } 
303+ } 
304+ 
305+ impl < ' a >  TryFrom < & ' a  String >  for  BorrowedStr < ' a >  { 
306+     type  Error  = Error ; 
307+ 
308+     #[ inline]  
309+     fn  try_from ( value :  & ' a  String )  -> Result < Self >  { 
310+         let  BorrowedBytes  {  buf,  borrow,  _lua }  = BorrowedBytes :: from ( value) ; 
311+         let  buf = str:: from_utf8 ( buf) . map_err ( |e| Error :: FromLuaConversionError  { 
312+             from :  "string" , 
313+             to :  "&str" . to_string ( ) , 
314+             message :  Some ( e. to_string ( ) ) , 
315+         } ) ?; 
316+         Ok ( Self  {  buf,  borrow,  _lua } ) 
301317    } 
302318} 
303319
304320/// A borrowed byte slice (`&[u8]`) that holds a strong reference to the Lua state. 
305- pub  struct  BorrowedBytes < ' a > ( & ' a  [ u8 ] ,  #[ allow( unused) ]   Lua ) ; 
321+ pub  struct  BorrowedBytes < ' a >  { 
322+     // `buf` points to a readonly memory managed by Lua 
323+     pub ( crate )  buf :  & ' a  [ u8 ] , 
324+     pub ( crate )  borrow :  Cow < ' a ,  String > , 
325+     pub ( crate )  _lua :  Lua , 
326+ } 
306327
307328impl  Deref  for  BorrowedBytes < ' _ >  { 
308329    type  Target  = [ u8 ] ; 
309330
310331    #[ inline( always) ]  
311332    fn  deref ( & self )  -> & [ u8 ]  { 
312-         self . 0 
333+         self . buf 
313334    } 
314335} 
315336
316337impl  Borrow < [ u8 ] >  for  BorrowedBytes < ' _ >  { 
317338    #[ inline( always) ]  
318339    fn  borrow ( & self )  -> & [ u8 ]  { 
319-         self . 0 
340+         self . buf 
320341    } 
321342} 
322343
323344impl  AsRef < [ u8 ] >  for  BorrowedBytes < ' _ >  { 
324345    #[ inline( always) ]  
325346    fn  as_ref ( & self )  -> & [ u8 ]  { 
326-         self . 0 
347+         self . buf 
327348    } 
328349} 
329350
330351impl  fmt:: Debug  for  BorrowedBytes < ' _ >  { 
331352    fn  fmt ( & self ,  f :  & mut  fmt:: Formatter )  -> fmt:: Result  { 
332-         self . 0 . fmt ( f) 
353+         self . buf . fmt ( f) 
333354    } 
334355} 
335356
@@ -338,7 +359,7 @@ where
338359    T :  AsRef < [ u8 ] > , 
339360{ 
340361    fn  eq ( & self ,  other :  & T )  -> bool  { 
341-         self . 0  == other. as_ref ( ) 
362+         self . buf  == other. as_ref ( ) 
342363    } 
343364} 
344365
@@ -349,22 +370,31 @@ where
349370    T :  AsRef < [ u8 ] > , 
350371{ 
351372    fn  partial_cmp ( & self ,  other :  & T )  -> Option < cmp:: Ordering >  { 
352-         self . 0 . partial_cmp ( other. as_ref ( ) ) 
373+         self . buf . partial_cmp ( other. as_ref ( ) ) 
353374    } 
354375} 
355376
356377impl  Ord  for  BorrowedBytes < ' _ >  { 
357378    fn  cmp ( & self ,  other :  & Self )  -> cmp:: Ordering  { 
358-         self . 0 . cmp ( other. 0 ) 
379+         self . buf . cmp ( other. buf ) 
359380    } 
360381} 
361382
362- impl < ' a >  IntoIterator  for  BorrowedBytes < ' a >  { 
383+ impl < ' a >  IntoIterator  for  & ' a   BorrowedBytes < ' _ >  { 
363384    type  Item  = & ' a  u8 ; 
364385    type  IntoIter  = slice:: Iter < ' a ,  u8 > ; 
365386
366387    fn  into_iter ( self )  -> Self :: IntoIter  { 
367-         self . 0 . iter ( ) 
388+         self . iter ( ) 
389+     } 
390+ } 
391+ 
392+ impl < ' a >  From < & ' a  String >  for  BorrowedBytes < ' a >  { 
393+     #[ inline]  
394+     fn  from ( value :  & ' a  String )  -> Self  { 
395+         let  ( buf,  _lua)  = unsafe  {  value. to_slice ( )  } ; 
396+         let  borrow = Cow :: Borrowed ( value) ; 
397+         Self  {  buf,  borrow,  _lua } 
368398    } 
369399} 
370400
0 commit comments