blob: 3fba2f5b75e1dd40c3ea16efb7ac0673740e28d4 [file] [log] [blame]
David Tolnay7db73692019-10-20 14:51:12 -04001use std::mem::{self, ManuallyDrop, MaybeUninit};
2use std::ptr;
3use std::slice;
4use std::str;
5
6#[repr(C)]
7pub struct RustString {
8 repr: String,
9}
10
11impl RustString {
12 pub fn from(s: String) -> Self {
13 RustString { repr: s }
14 }
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
20 pub fn into_string(self) -> String {
21 self.repr
22 }
23
24 pub fn as_string(&self) -> &String {
25 &self.repr
26 }
David Tolnay40226ab2020-03-03 00:05:35 -080027
28 pub fn as_mut_string(&mut self) -> &mut String {
29 &mut self.repr
30 }
David Tolnay7db73692019-10-20 14:51:12 -040031}
32
David Tolnay8c730492020-03-13 01:29:06 -070033#[export_name = "cxxbridge02$string$new"]
David Tolnay7db73692019-10-20 14:51:12 -040034unsafe extern "C" fn string_new(this: &mut MaybeUninit<String>) {
35 ptr::write(this.as_mut_ptr(), String::new());
36}
37
David Tolnay8c730492020-03-13 01:29:06 -070038#[export_name = "cxxbridge02$string$clone"]
David Tolnay7db73692019-10-20 14:51:12 -040039unsafe extern "C" fn string_clone(this: &mut MaybeUninit<String>, other: &String) {
40 ptr::write(this.as_mut_ptr(), other.clone());
41}
42
David Tolnay8c730492020-03-13 01:29:06 -070043#[export_name = "cxxbridge02$string$from"]
David Tolnay7db73692019-10-20 14:51:12 -040044unsafe extern "C" fn string_from(
45 this: &mut MaybeUninit<String>,
46 ptr: *const u8,
47 len: usize,
48) -> bool {
49 let slice = slice::from_raw_parts(ptr, len);
50 match str::from_utf8(slice) {
51 Ok(s) => {
52 ptr::write(this.as_mut_ptr(), s.to_owned());
53 true
54 }
55 Err(_) => false,
56 }
57}
58
David Tolnay8c730492020-03-13 01:29:06 -070059#[export_name = "cxxbridge02$string$drop"]
David Tolnay7db73692019-10-20 14:51:12 -040060unsafe extern "C" fn string_drop(this: &mut ManuallyDrop<String>) {
61 ManuallyDrop::drop(this);
62}
63
David Tolnay8c730492020-03-13 01:29:06 -070064#[export_name = "cxxbridge02$string$ptr"]
David Tolnay7db73692019-10-20 14:51:12 -040065unsafe extern "C" fn string_ptr(this: &String) -> *const u8 {
66 this.as_ptr()
67}
68
David Tolnay8c730492020-03-13 01:29:06 -070069#[export_name = "cxxbridge02$string$len"]
David Tolnay7db73692019-10-20 14:51:12 -040070unsafe extern "C" fn string_len(this: &String) -> usize {
71 this.len()
72}
73
David Tolnayaa77e822020-04-24 15:43:05 -070074const_assert_eq!(mem::size_of::<[usize; 3]>(), mem::size_of::<String>());
75const_assert_eq!(mem::align_of::<usize>(), mem::align_of::<String>());