blob: 5756efadf53ca7a747c260222a2c4e0c6dc8df37 [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 {
17 unsafe { std::mem::transmute::<&String, &RustString>(s) }
18 }
19
20 pub fn into_string(self) -> String {
21 self.repr
22 }
23
24 pub fn as_string(&self) -> &String {
25 &self.repr
26 }
27}
28
29#[export_name = "cxxbridge00$rust_string$new"]
30unsafe extern "C" fn string_new(this: &mut MaybeUninit<String>) {
31 ptr::write(this.as_mut_ptr(), String::new());
32}
33
34#[export_name = "cxxbridge00$rust_string$clone"]
35unsafe extern "C" fn string_clone(this: &mut MaybeUninit<String>, other: &String) {
36 ptr::write(this.as_mut_ptr(), other.clone());
37}
38
39#[export_name = "cxxbridge00$rust_string$from"]
40unsafe extern "C" fn string_from(
41 this: &mut MaybeUninit<String>,
42 ptr: *const u8,
43 len: usize,
44) -> bool {
45 let slice = slice::from_raw_parts(ptr, len);
46 match str::from_utf8(slice) {
47 Ok(s) => {
48 ptr::write(this.as_mut_ptr(), s.to_owned());
49 true
50 }
51 Err(_) => false,
52 }
53}
54
55#[export_name = "cxxbridge00$rust_string$drop"]
56unsafe extern "C" fn string_drop(this: &mut ManuallyDrop<String>) {
57 ManuallyDrop::drop(this);
58}
59
60#[export_name = "cxxbridge00$rust_string$ptr"]
61unsafe extern "C" fn string_ptr(this: &String) -> *const u8 {
62 this.as_ptr()
63}
64
65#[export_name = "cxxbridge00$rust_string$len"]
66unsafe extern "C" fn string_len(this: &String) -> usize {
67 this.len()
68}
69
70fn _assert() {
71 let _: [(); mem::size_of::<[usize; 3]>()] = [(); mem::size_of::<String>()];
72 let _: [(); mem::align_of::<usize>()] = [(); mem::align_of::<String>()];
73}