blob: 051e35c3b9b765ef9829aac855a0a53b74dc9958 [file] [log] [blame]
David Tolnaycb07a842021-04-16 16:08:52 -07001#![allow(missing_docs)]
2
David Tolnayc5a52f92020-09-14 00:43:29 -04003use alloc::string::String;
David Tolnay56377fc2021-04-10 12:18:31 -07004use core::mem::{self, MaybeUninit};
David Tolnaye0e39352021-04-15 15:51:17 -07005use core::ptr;
David Tolnay7db73692019-10-20 14:51:12 -04006
David Tolnay56377fc2021-04-10 12:18:31 -07007// ABI compatible with C++ rust::String (not necessarily alloc::string::String).
David Tolnay7db73692019-10-20 14:51:12 -04008#[repr(C)]
9pub struct RustString {
David Tolnay56377fc2021-04-10 12:18:31 -070010 repr: [MaybeUninit<usize>; mem::size_of::<String>() / mem::size_of::<usize>()],
David Tolnay7db73692019-10-20 14:51:12 -040011}
12
13impl RustString {
14 pub fn from(s: String) -> Self {
David Tolnay56377fc2021-04-10 12:18:31 -070015 unsafe { mem::transmute::<String, RustString>(s) }
David Tolnay7db73692019-10-20 14:51:12 -040016 }
17
18 pub fn from_ref(s: &String) -> &Self {
David Tolnaydb96ed92020-03-18 17:20:39 -070019 unsafe { &*(s as *const String as *const RustString) }
David Tolnay7db73692019-10-20 14:51:12 -040020 }
21
David Tolnayf1c7f322020-08-27 00:46:01 -070022 pub fn from_mut(s: &mut String) -> &mut Self {
23 unsafe { &mut *(s as *mut String as *mut RustString) }
24 }
25
David Tolnay7db73692019-10-20 14:51:12 -040026 pub fn into_string(self) -> String {
David Tolnay56377fc2021-04-10 12:18:31 -070027 unsafe { mem::transmute::<RustString, String>(self) }
David Tolnay7db73692019-10-20 14:51:12 -040028 }
29
30 pub fn as_string(&self) -> &String {
David Tolnay56377fc2021-04-10 12:18:31 -070031 unsafe { &*(self as *const RustString as *const String) }
David Tolnay7db73692019-10-20 14:51:12 -040032 }
David Tolnay40226ab2020-03-03 00:05:35 -080033
34 pub fn as_mut_string(&mut self) -> &mut String {
David Tolnay56377fc2021-04-10 12:18:31 -070035 unsafe { &mut *(self as *mut RustString as *mut String) }
David Tolnay40226ab2020-03-03 00:05:35 -080036 }
David Tolnay7db73692019-10-20 14:51:12 -040037}
38
David Tolnaye0e39352021-04-15 15:51:17 -070039impl Drop for RustString {
40 fn drop(&mut self) {
41 unsafe { ptr::drop_in_place(self.as_mut_string()) }
42 }
43}
44
David Tolnay56377fc2021-04-10 12:18:31 -070045const_assert_eq!(mem::size_of::<[usize; 3]>(), mem::size_of::<RustString>());
46const_assert_eq!(mem::size_of::<String>(), mem::size_of::<RustString>());
47const_assert_eq!(mem::align_of::<String>(), mem::align_of::<RustString>());