aboutsummaryrefslogtreecommitdiff
path: root/src/rust_str.rs
blob: b1b46e3e94a5a21a8d9b461cb05c43c3c0547f75 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#![allow(missing_docs)]

use core::mem::{self, MaybeUninit};
use core::ptr::NonNull;
use core::str;

// ABI compatible with C++ rust::Str (not necessarily &str).
#[repr(C)]
pub struct RustStr {
    repr: [MaybeUninit<usize>; mem::size_of::<NonNull<str>>() / mem::size_of::<usize>()],
}

impl RustStr {
    pub fn from(repr: &str) -> Self {
        let repr = NonNull::from(repr);
        unsafe { mem::transmute::<NonNull<str>, RustStr>(repr) }
    }

    pub unsafe fn as_str<'a>(self) -> &'a str {
        unsafe {
            let repr = mem::transmute::<RustStr, NonNull<str>>(self);
            &*repr.as_ptr()
        }
    }
}

const_assert_eq!(mem::size_of::<NonNull<str>>(), mem::size_of::<RustStr>());
const_assert_eq!(mem::align_of::<NonNull<str>>(), mem::align_of::<RustStr>());