| David Tolnay | 3eba201 | 2021-04-08 22:20:09 -0700 | [diff] [blame] | 1 | use core::mem::{self, MaybeUninit}; |
| David Tolnay | 3384c14 | 2020-09-14 00:26:47 -0400 | [diff] [blame] | 2 | use core::ptr::NonNull; |
| David Tolnay | 3384c14 | 2020-09-14 00:26:47 -0400 | [diff] [blame] | 3 | use core::str; |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 4 | |
| David Tolnay | 3eba201 | 2021-04-08 22:20:09 -0700 | [diff] [blame] | 5 | // ABI compatible with C++ rust::Str (not necessarily &str). |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 6 | #[repr(C)] |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 7 | pub struct RustStr { |
| David Tolnay | 3eba201 | 2021-04-08 22:20:09 -0700 | [diff] [blame] | 8 | repr: [MaybeUninit<usize>; mem::size_of::<NonNull<str>>() / mem::size_of::<usize>()], |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 9 | } |
| 10 | |
| 11 | impl RustStr { |
| David Tolnay | 1202de5 | 2021-01-02 01:26:33 -0800 | [diff] [blame] | 12 | pub fn from(repr: &str) -> Self { |
| 13 | let repr = NonNull::from(repr); |
| David Tolnay | 3eba201 | 2021-04-08 22:20:09 -0700 | [diff] [blame] | 14 | unsafe { mem::transmute::<NonNull<str>, RustStr>(repr) } |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 15 | } |
| 16 | |
| 17 | pub unsafe fn as_str<'a>(self) -> &'a str { |
| David Tolnay | 3eba201 | 2021-04-08 22:20:09 -0700 | [diff] [blame] | 18 | let repr = mem::transmute::<RustStr, NonNull<str>>(self); |
| David Tolnay | c32b58b | 2021-04-10 12:11:29 -0700 | [diff] [blame] | 19 | &*repr.as_ptr() |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 20 | } |
| 21 | } |
| 22 | |
| David Tolnay | 3eba201 | 2021-04-08 22:20:09 -0700 | [diff] [blame] | 23 | const_assert_eq!(mem::size_of::<NonNull<str>>(), mem::size_of::<RustStr>()); |
| 24 | const_assert_eq!(mem::align_of::<NonNull<str>>(), mem::align_of::<RustStr>()); |