blob: 77a83f628bdd76d96b9670c514da54c7f060bb5b [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 Tolnay7db73692019-10-20 14:51:12 -04003
David Tolnay56377fc2021-04-10 12:18:31 -07004// ABI compatible with C++ rust::String (not necessarily alloc::string::String).
David Tolnay7db73692019-10-20 14:51:12 -04005#[repr(C)]
6pub struct RustString {
David Tolnay56377fc2021-04-10 12:18:31 -07007 repr: [MaybeUninit<usize>; mem::size_of::<String>() / mem::size_of::<usize>()],
David Tolnay7db73692019-10-20 14:51:12 -04008}
9
10impl RustString {
11 pub fn from(s: String) -> Self {
David Tolnay56377fc2021-04-10 12:18:31 -070012 unsafe { mem::transmute::<String, RustString>(s) }
David Tolnay7db73692019-10-20 14:51:12 -040013 }
14
15 pub fn from_ref(s: &String) -> &Self {
David Tolnaydb96ed92020-03-18 17:20:39 -070016 unsafe { &*(s as *const String as *const RustString) }
David Tolnay7db73692019-10-20 14:51:12 -040017 }
18
David Tolnayf1c7f322020-08-27 00:46:01 -070019 pub fn from_mut(s: &mut String) -> &mut Self {
20 unsafe { &mut *(s as *mut String as *mut RustString) }
21 }
22
David Tolnay7db73692019-10-20 14:51:12 -040023 pub fn into_string(self) -> String {
David Tolnay56377fc2021-04-10 12:18:31 -070024 unsafe { mem::transmute::<RustString, String>(self) }
David Tolnay7db73692019-10-20 14:51:12 -040025 }
26
27 pub fn as_string(&self) -> &String {
David Tolnay56377fc2021-04-10 12:18:31 -070028 unsafe { &*(self as *const RustString as *const String) }
David Tolnay7db73692019-10-20 14:51:12 -040029 }
David Tolnay40226ab2020-03-03 00:05:35 -080030
31 pub fn as_mut_string(&mut self) -> &mut String {
David Tolnay56377fc2021-04-10 12:18:31 -070032 unsafe { &mut *(self as *mut RustString as *mut String) }
David Tolnay40226ab2020-03-03 00:05:35 -080033 }
David Tolnay7db73692019-10-20 14:51:12 -040034}
35
David Tolnay56377fc2021-04-10 12:18:31 -070036const_assert_eq!(mem::size_of::<[usize; 3]>(), mem::size_of::<RustString>());
37const_assert_eq!(mem::size_of::<String>(), mem::size_of::<RustString>());
38const_assert_eq!(mem::align_of::<String>(), mem::align_of::<RustString>());