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, _guard } = 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, _guard }
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,44 @@ 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
+ pub ( crate ) buf : * const str ,
239
+ pub ( crate ) borrow : Cow < ' a , String > ,
240
+ pub ( crate ) _guard : Lua ,
241
+ }
242
242
243
243
impl Deref for BorrowedStr < ' _ > {
244
244
type Target = str ;
245
245
246
246
#[ inline( always) ]
247
247
fn deref ( & self ) -> & str {
248
- self . 0
248
+ unsafe { & * self . buf }
249
249
}
250
250
}
251
251
252
252
impl Borrow < str > for BorrowedStr < ' _ > {
253
253
#[ inline( always) ]
254
254
fn borrow ( & self ) -> & str {
255
- self . 0
255
+ self . deref ( )
256
256
}
257
257
}
258
258
259
259
impl AsRef < str > for BorrowedStr < ' _ > {
260
260
#[ inline( always) ]
261
261
fn as_ref ( & self ) -> & str {
262
- self . 0
262
+ self . deref ( )
263
263
}
264
264
}
265
265
266
266
impl fmt:: Display for BorrowedStr < ' _ > {
267
267
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
268
- self . 0 . fmt ( f)
268
+ self . as_ref ( ) . fmt ( f)
269
269
}
270
270
}
271
271
272
272
impl fmt:: Debug for BorrowedStr < ' _ > {
273
273
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
274
- self . 0 . fmt ( f)
274
+ self . as_ref ( ) . fmt ( f)
275
275
}
276
276
}
277
277
@@ -280,7 +280,7 @@ where
280
280
T : AsRef < str > ,
281
281
{
282
282
fn eq ( & self , other : & T ) -> bool {
283
- self . 0 == other. as_ref ( )
283
+ self . as_ref ( ) == other. as_ref ( )
284
284
}
285
285
}
286
286
@@ -291,45 +291,64 @@ where
291
291
T : AsRef < str > ,
292
292
{
293
293
fn partial_cmp ( & self , other : & T ) -> Option < cmp:: Ordering > {
294
- self . 0 . partial_cmp ( other. as_ref ( ) )
294
+ self . as_ref ( ) . partial_cmp ( other. as_ref ( ) )
295
295
}
296
296
}
297
297
298
298
impl Ord for BorrowedStr < ' _ > {
299
299
fn cmp ( & self , other : & Self ) -> cmp:: Ordering {
300
- self . 0 . cmp ( other. 0 )
300
+ self . as_ref ( ) . cmp ( other. as_ref ( ) )
301
+ }
302
+ }
303
+
304
+ impl < ' a > TryFrom < & ' a String > for BorrowedStr < ' a > {
305
+ type Error = Error ;
306
+
307
+ #[ inline]
308
+ fn try_from ( value : & ' a String ) -> Result < Self > {
309
+ let BorrowedBytes { buf, borrow, _guard } = BorrowedBytes :: from ( value) ;
310
+ let buf = str:: from_utf8 ( unsafe { & * buf } ) . map_err ( |e| Error :: FromLuaConversionError {
311
+ from : "string" ,
312
+ to : "&str" . to_string ( ) ,
313
+ message : Some ( e. to_string ( ) ) ,
314
+ } ) ?;
315
+ Ok ( Self { buf, borrow, _guard } )
301
316
}
302
317
}
303
318
304
319
/// A borrowed byte slice (`&[u8]`) that holds a strong reference to the Lua state.
305
- pub struct BorrowedBytes < ' a > ( & ' a [ u8 ] , #[ allow( unused) ] Lua ) ;
320
+ pub struct BorrowedBytes < ' a > {
321
+ pub ( crate ) buf : * const [ u8 ] ,
322
+ pub ( crate ) borrow : Cow < ' a , String > ,
323
+ pub ( crate ) _guard : Lua ,
324
+ }
306
325
307
326
impl Deref for BorrowedBytes < ' _ > {
308
327
type Target = [ u8 ] ;
309
328
310
329
#[ inline( always) ]
311
330
fn deref ( & self ) -> & [ u8 ] {
312
- self . 0
331
+ unsafe { & * self . buf }
313
332
}
314
333
}
315
334
316
335
impl Borrow < [ u8 ] > for BorrowedBytes < ' _ > {
317
336
#[ inline( always) ]
318
337
fn borrow ( & self ) -> & [ u8 ] {
319
- self . 0
338
+ self . deref ( )
320
339
}
321
340
}
322
341
323
342
impl AsRef < [ u8 ] > for BorrowedBytes < ' _ > {
324
343
#[ inline( always) ]
325
344
fn as_ref ( & self ) -> & [ u8 ] {
326
- self . 0
345
+ self . deref ( )
327
346
}
328
347
}
329
348
330
349
impl fmt:: Debug for BorrowedBytes < ' _ > {
331
350
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
332
- self . 0 . fmt ( f)
351
+ self . as_ref ( ) . fmt ( f)
333
352
}
334
353
}
335
354
@@ -338,7 +357,7 @@ where
338
357
T : AsRef < [ u8 ] > ,
339
358
{
340
359
fn eq ( & self , other : & T ) -> bool {
341
- self . 0 == other. as_ref ( )
360
+ self . as_ref ( ) == other. as_ref ( )
342
361
}
343
362
}
344
363
@@ -349,22 +368,31 @@ where
349
368
T : AsRef < [ u8 ] > ,
350
369
{
351
370
fn partial_cmp ( & self , other : & T ) -> Option < cmp:: Ordering > {
352
- self . 0 . partial_cmp ( other. as_ref ( ) )
371
+ self . as_ref ( ) . partial_cmp ( other. as_ref ( ) )
353
372
}
354
373
}
355
374
356
375
impl Ord for BorrowedBytes < ' _ > {
357
376
fn cmp ( & self , other : & Self ) -> cmp:: Ordering {
358
- self . 0 . cmp ( other. 0 )
377
+ self . as_ref ( ) . cmp ( other. as_ref ( ) )
359
378
}
360
379
}
361
380
362
- impl < ' a > IntoIterator for BorrowedBytes < ' a > {
381
+ impl < ' a > IntoIterator for & ' a BorrowedBytes < ' _ > {
363
382
type Item = & ' a u8 ;
364
383
type IntoIter = slice:: Iter < ' a , u8 > ;
365
384
366
385
fn into_iter ( self ) -> Self :: IntoIter {
367
- self . 0 . iter ( )
386
+ self . iter ( )
387
+ }
388
+ }
389
+
390
+ impl < ' a > From < & ' a String > for BorrowedBytes < ' a > {
391
+ #[ inline]
392
+ fn from ( value : & ' a String ) -> Self {
393
+ let ( buf, _guard) = unsafe { value. to_slice ( ) } ;
394
+ let borrow = Cow :: Borrowed ( value) ;
395
+ Self { buf, borrow, _guard }
368
396
}
369
397
}
370
398
0 commit comments