1
- use std:: borrow:: Borrow ;
1
+ use std:: borrow:: { Borrow , Cow } ;
2
2
use std:: hash:: { Hash , Hasher } ;
3
3
use std:: ops:: Deref ;
4
4
use std:: os:: raw:: { c_int, c_void} ;
@@ -44,13 +44,7 @@ impl String {
44
44
/// ```
45
45
#[ inline]
46
46
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 )
54
48
}
55
49
56
50
/// Converts this string to a [`StdString`].
@@ -109,19 +103,21 @@ impl String {
109
103
/// ```
110
104
#[ inline]
111
105
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 )
114
107
}
115
108
116
109
/// Get the bytes that make up this string, including the trailing nul byte.
117
110
pub 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 }
120
115
}
121
116
117
+ // Does not return the terminating nul byte
122
118
unsafe fn to_slice ( & self ) -> ( & [ u8 ] , Lua ) {
123
119
let lua = self . 0 . lua . upgrade ( ) ;
124
- let slice = unsafe {
120
+ let slice = {
125
121
let rawlua = lua. lock ( ) ;
126
122
let ref_thread = rawlua. ref_thread ( ) ;
127
123
@@ -134,7 +130,7 @@ impl String {
134
130
// string type
135
131
let mut size = 0 ;
136
132
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)
138
134
} ;
139
135
( slice, lua)
140
136
}
@@ -238,40 +234,45 @@ impl fmt::Display for Display<'_> {
238
234
}
239
235
240
236
/// 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
+ }
242
243
243
244
impl Deref for BorrowedStr < ' _ > {
244
245
type Target = str ;
245
246
246
247
#[ inline( always) ]
247
248
fn deref ( & self ) -> & str {
248
- self . 0
249
+ self . buf
249
250
}
250
251
}
251
252
252
253
impl Borrow < str > for BorrowedStr < ' _ > {
253
254
#[ inline( always) ]
254
255
fn borrow ( & self ) -> & str {
255
- self . 0
256
+ self . buf
256
257
}
257
258
}
258
259
259
260
impl AsRef < str > for BorrowedStr < ' _ > {
260
261
#[ inline( always) ]
261
262
fn as_ref ( & self ) -> & str {
262
- self . 0
263
+ self . buf
263
264
}
264
265
}
265
266
266
267
impl fmt:: Display for BorrowedStr < ' _ > {
267
268
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
268
- self . 0 . fmt ( f)
269
+ self . buf . fmt ( f)
269
270
}
270
271
}
271
272
272
273
impl fmt:: Debug for BorrowedStr < ' _ > {
273
274
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
274
- self . 0 . fmt ( f)
275
+ self . buf . fmt ( f)
275
276
}
276
277
}
277
278
@@ -280,7 +281,7 @@ where
280
281
T : AsRef < str > ,
281
282
{
282
283
fn eq ( & self , other : & T ) -> bool {
283
- self . 0 == other. as_ref ( )
284
+ self . buf == other. as_ref ( )
284
285
}
285
286
}
286
287
@@ -291,45 +292,65 @@ where
291
292
T : AsRef < str > ,
292
293
{
293
294
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 ( ) )
295
296
}
296
297
}
297
298
298
299
impl Ord for BorrowedStr < ' _ > {
299
300
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 } )
301
317
}
302
318
}
303
319
304
320
/// 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
+ }
306
327
307
328
impl Deref for BorrowedBytes < ' _ > {
308
329
type Target = [ u8 ] ;
309
330
310
331
#[ inline( always) ]
311
332
fn deref ( & self ) -> & [ u8 ] {
312
- self . 0
333
+ self . buf
313
334
}
314
335
}
315
336
316
337
impl Borrow < [ u8 ] > for BorrowedBytes < ' _ > {
317
338
#[ inline( always) ]
318
339
fn borrow ( & self ) -> & [ u8 ] {
319
- self . 0
340
+ self . buf
320
341
}
321
342
}
322
343
323
344
impl AsRef < [ u8 ] > for BorrowedBytes < ' _ > {
324
345
#[ inline( always) ]
325
346
fn as_ref ( & self ) -> & [ u8 ] {
326
- self . 0
347
+ self . buf
327
348
}
328
349
}
329
350
330
351
impl fmt:: Debug for BorrowedBytes < ' _ > {
331
352
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
332
- self . 0 . fmt ( f)
353
+ self . buf . fmt ( f)
333
354
}
334
355
}
335
356
@@ -338,7 +359,7 @@ where
338
359
T : AsRef < [ u8 ] > ,
339
360
{
340
361
fn eq ( & self , other : & T ) -> bool {
341
- self . 0 == other. as_ref ( )
362
+ self . buf == other. as_ref ( )
342
363
}
343
364
}
344
365
@@ -349,22 +370,31 @@ where
349
370
T : AsRef < [ u8 ] > ,
350
371
{
351
372
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 ( ) )
353
374
}
354
375
}
355
376
356
377
impl Ord for BorrowedBytes < ' _ > {
357
378
fn cmp ( & self , other : & Self ) -> cmp:: Ordering {
358
- self . 0 . cmp ( other. 0 )
379
+ self . buf . cmp ( other. buf )
359
380
}
360
381
}
361
382
362
- impl < ' a > IntoIterator for BorrowedBytes < ' a > {
383
+ impl < ' a > IntoIterator for & ' a BorrowedBytes < ' _ > {
363
384
type Item = & ' a u8 ;
364
385
type IntoIter = slice:: Iter < ' a , u8 > ;
365
386
366
387
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 }
368
398
}
369
399
}
370
400
0 commit comments