1 #![allow(non_snake_case)]
2 
3 extern crate nsstring;
4 
5 use nsstring::*;
6 use std::ffi::CString;
7 use std::fmt::Write;
8 use std::os::raw::c_char;
9 
nonfatal_fail(msg: String)10 fn nonfatal_fail(msg: String) {
11     extern "C" {
12         fn GTest_ExpectFailure(message: *const c_char);
13     }
14     unsafe {
15         let msg = CString::new(msg).unwrap();
16         GTest_ExpectFailure(msg.as_ptr());
17     }
18 }
19 
20 /// This macro checks if the two arguments are equal, and causes a non-fatal
21 /// GTest test failure if they are not.
22 macro_rules! expect_eq {
23     ($x:expr, $y:expr) => {
24         match (&$x, &$y) {
25             (x, y) => {
26                 if *x != *y {
27                     nonfatal_fail(format!(
28                         "check failed: (`{:?}` == `{:?}`) at {}:{}",
29                         x,
30                         y,
31                         file!(),
32                         line!()
33                     ))
34                 }
35             }
36         }
37     };
38 }
39 
40 #[no_mangle]
Rust_StringFromCpp(cs: *const nsACString, s: *const nsAString)41 pub extern "C" fn Rust_StringFromCpp(cs: *const nsACString, s: *const nsAString) {
42     unsafe {
43         expect_eq!(&*cs, "Hello, World!");
44         expect_eq!(&*s, "Hello, World!");
45     }
46 }
47 
48 #[no_mangle]
Rust_AssignFromRust(cs: *mut nsACString, s: *mut nsAString)49 pub extern "C" fn Rust_AssignFromRust(cs: *mut nsACString, s: *mut nsAString) {
50     unsafe {
51         (*cs).assign(&nsCString::from("Hello, World!"));
52         expect_eq!(&*cs, "Hello, World!");
53         (*s).assign(&nsString::from("Hello, World!"));
54         expect_eq!(&*s, "Hello, World!");
55     }
56 }
57 
58 extern "C" {
Cpp_AssignFromCpp(cs: *mut nsACString, s: *mut nsAString)59     fn Cpp_AssignFromCpp(cs: *mut nsACString, s: *mut nsAString);
60 }
61 
62 #[no_mangle]
Rust_AssignFromCpp()63 pub extern "C" fn Rust_AssignFromCpp() {
64     let mut cs = nsCString::new();
65     let mut s = nsString::new();
66     unsafe {
67         Cpp_AssignFromCpp(&mut *cs, &mut *s);
68     }
69     expect_eq!(cs, "Hello, World!");
70     expect_eq!(s, "Hello, World!");
71 }
72 
73 #[no_mangle]
Rust_StringWrite()74 pub extern "C" fn Rust_StringWrite() {
75     let mut cs = nsCString::new();
76     let mut s = nsString::new();
77 
78     write!(s, "a").unwrap();
79     write!(cs, "a").unwrap();
80     expect_eq!(s, "a");
81     expect_eq!(cs, "a");
82     write!(s, "bc").unwrap();
83     write!(cs, "bc").unwrap();
84     expect_eq!(s, "abc");
85     expect_eq!(cs, "abc");
86     write!(s, "{}", 123).unwrap();
87     write!(cs, "{}", 123).unwrap();
88     expect_eq!(s, "abc123");
89     expect_eq!(cs, "abc123");
90 }
91 
92 #[no_mangle]
Rust_FromEmptyRustString()93 pub extern "C" fn Rust_FromEmptyRustString() {
94     let mut test = nsString::from("Blah");
95     test.assign_utf8(&nsCString::from(String::new()));
96     assert!(test.is_empty());
97 }
98 
99 #[no_mangle]
Rust_WriteToBufferFromRust( cs: *mut nsACString, s: *mut nsAString, fallible_cs: *mut nsACString, fallible_s: *mut nsAString, )100 pub extern "C" fn Rust_WriteToBufferFromRust(
101     cs: *mut nsACString,
102     s: *mut nsAString,
103     fallible_cs: *mut nsACString,
104     fallible_s: *mut nsAString,
105 ) {
106     unsafe {
107         let cs_buf = (*cs).to_mut();
108         let s_buf = (*s).to_mut();
109         let fallible_cs_buf = (*fallible_cs).fallible_to_mut().unwrap();
110         let fallible_s_buf = (*fallible_s).fallible_to_mut().unwrap();
111 
112         cs_buf[0] = b'A';
113         cs_buf[1] = b'B';
114         cs_buf[2] = b'C';
115         s_buf[0] = b'A' as u16;
116         s_buf[1] = b'B' as u16;
117         s_buf[2] = b'C' as u16;
118         fallible_cs_buf[0] = b'A';
119         fallible_cs_buf[1] = b'B';
120         fallible_cs_buf[2] = b'C';
121         fallible_s_buf[0] = b'A' as u16;
122         fallible_s_buf[1] = b'B' as u16;
123         fallible_s_buf[2] = b'C' as u16;
124     }
125 }
126 
127 #[no_mangle]
Rust_VoidStringFromRust(cs: &mut nsACString, s: &mut nsAString)128 pub extern "C" fn Rust_VoidStringFromRust(cs: &mut nsACString, s: &mut nsAString) {
129     cs.set_is_void(true);
130     s.set_is_void(true);
131 }
132