blob: 51336941876c475aa41e77db10b77b6d083d6e8b [file] [log] [blame]
David Tolnayc5a52f92020-09-14 00:43:29 -04001use alloc::string::String;
David Tolnay56377fc2021-04-10 12:18:31 -07002use core::mem::{self, MaybeUninit};
David Tolnaye0e39352021-04-15 15:51:17 -07003use core::ptr;
David Tolnay7db73692019-10-20 14:51:12 -04004
David Tolnay56377fc2021-04-10 12:18:31 -07005// ABI compatible with C++ rust::String (not necessarily alloc::string::String).
David Tolnay7db73692019-10-20 14:51:12 -04006#[repr(C)]
7pub struct RustString {
David Tolnay56377fc2021-04-10 12:18:31 -07008 repr: [MaybeUninit<usize>; mem::size_of::<String>() / mem::size_of::<usize>()],
David Tolnay7db73692019-10-20 14:51:12 -04009}
10
11impl RustString {
12 pub fn from(s: String) -> Self {
David Tolnay56377fc2021-04-10 12:18:31 -070013 unsafe { mem::transmute::<String, RustString>(s) }
David Tolnay7db73692019-10-20 14:51:12 -040014 }
15
16 pub fn from_ref(s: &String) -> &Self {
David Tolnaydb96ed92020-03-18 17:20:39 -070017 unsafe { &*(s as *const String as *const RustString) }
David Tolnay7db73692019-10-20 14:51:12 -040018 }
19
David Tolnayf1c7f322020-08-27 00:46:01 -070020 pub fn from_mut(s: &mut String) -> &mut Self {
21 unsafe { &mut *(s as *mut String as *mut RustString) }
22 }
23
David Tolnay7db73692019-10-20 14:51:12 -040024 pub fn into_string(self) -> String {
David Tolnay56377fc2021-04-10 12:18:31 -070025 unsafe { mem::transmute::<RustString, String>(self) }
David Tolnay7db73692019-10-20 14:51:12 -040026 }
27
28 pub fn as_string(&self) -> &String {
David Tolnay56377fc2021-04-10 12:18:31 -070029 unsafe { &*(self as *const RustString as *const String) }
David Tolnay7db73692019-10-20 14:51:12 -040030 }
David Tolnay40226ab2020-03-03 00:05:35 -080031
32 pub fn as_mut_string(&mut self) -> &mut String {
David Tolnay56377fc2021-04-10 12:18:31 -070033 unsafe { &mut *(self as *mut RustString as *mut String) }
David Tolnay40226ab2020-03-03 00:05:35 -080034 }
David Tolnay7db73692019-10-20 14:51:12 -040035}
36
David Tolnaye0e39352021-04-15 15:51:17 -070037impl Drop for RustString {
38 fn drop(&mut self) {
39 unsafe { ptr::drop_in_place(self.as_mut_string()) }
40 }
41}
42
David Tolnay56377fc2021-04-10 12:18:31 -070043const_assert_eq!(mem::size_of::<[usize; 3]>(), mem::size_of::<RustString>());
44const_assert_eq!(mem::size_of::<String>(), mem::size_of::<RustString>());
45const_assert_eq!(mem::align_of::<String>(), mem::align_of::<RustString>());