1 #![allow(non_snake_case)]
2 
3 #[macro_use]
4 extern crate nsstring;
5 
6 use std::fmt::Write;
7 use std::ffi::CString;
8 use std::os::raw::c_char;
9 use nsstring::*;
10 
nonfatal_fail(msg: String)11 fn nonfatal_fail(msg: String) {
12     extern "C" {
13         fn GTest_ExpectFailure(message: *const c_char);
14     }
15     unsafe {
16         GTest_ExpectFailure(CString::new(msg).unwrap().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) => if *x != *y {
26                 nonfatal_fail(format!("check failed: (`{:?}` == `{:?}`) at {}:{}",
27                                       x, y, file!(), line!()))
28             }
29         }
30     }
31 }
32 
33 #[no_mangle]
Rust_StringFromCpp(cs: *const nsACString, s: *const nsAString)34 pub extern fn Rust_StringFromCpp(cs: *const nsACString, s: *const nsAString) {
35     unsafe {
36         expect_eq!(&*cs, "Hello, World!");
37         expect_eq!(&*s, "Hello, World!");
38     }
39 }
40 
41 #[no_mangle]
Rust_AssignFromRust(cs: *mut nsACString, s: *mut nsAString)42 pub extern fn Rust_AssignFromRust(cs: *mut nsACString, s: *mut nsAString) {
43     unsafe {
44         (*cs).assign(&nsCString::from("Hello, World!"));
45         expect_eq!(&*cs, "Hello, World!");
46         (*s).assign(&nsString::from("Hello, World!"));
47         expect_eq!(&*s, "Hello, World!");
48     }
49 }
50 
51 extern "C" {
Cpp_AssignFromCpp(cs: *mut nsACString, s: *mut nsAString)52     fn Cpp_AssignFromCpp(cs: *mut nsACString, s: *mut nsAString);
53 }
54 
55 #[no_mangle]
Rust_AssignFromCpp()56 pub extern fn Rust_AssignFromCpp() {
57     let mut cs = nsCString::new();
58     let mut s = nsString::new();
59     unsafe {
60         Cpp_AssignFromCpp(&mut *cs, &mut *s);
61     }
62     expect_eq!(cs, "Hello, World!");
63     expect_eq!(s, "Hello, World!");
64 }
65 
66 #[no_mangle]
Rust_FixedAssignFromCpp()67 pub extern fn Rust_FixedAssignFromCpp() {
68     let mut cs_buf: [u8; 64] = [0; 64];
69     let cs_buf_ptr = &cs_buf as *const _ as usize;
70     let mut s_buf: [u16; 64] = [0; 64];
71     let s_buf_ptr = &s_buf as *const _ as usize;
72     let mut cs = nsFixedCString::new(&mut cs_buf);
73     let mut s = nsFixedString::new(&mut s_buf);
74     unsafe {
75         Cpp_AssignFromCpp(&mut *cs, &mut *s);
76     }
77     expect_eq!(cs, "Hello, World!");
78     expect_eq!(s, "Hello, World!");
79     expect_eq!(cs.as_ptr() as usize, cs_buf_ptr);
80     expect_eq!(s.as_ptr() as usize, s_buf_ptr);
81 }
82 
83 #[no_mangle]
Rust_AutoAssignFromCpp()84 pub extern fn Rust_AutoAssignFromCpp() {
85     ns_auto_cstring!(cs);
86     ns_auto_string!(s);
87     unsafe {
88         Cpp_AssignFromCpp(&mut *cs, &mut *s);
89     }
90     expect_eq!(cs, "Hello, World!");
91     expect_eq!(s, "Hello, World!");
92 }
93 
94 #[no_mangle]
Rust_StringWrite()95 pub extern fn Rust_StringWrite() {
96     ns_auto_cstring!(cs);
97     ns_auto_string!(s);
98 
99     write!(s, "a").unwrap();
100     write!(cs, "a").unwrap();
101     expect_eq!(s, "a");
102     expect_eq!(cs, "a");
103     write!(s, "bc").unwrap();
104     write!(cs, "bc").unwrap();
105     expect_eq!(s, "abc");
106     expect_eq!(cs, "abc");
107     write!(s, "{}", 123).unwrap();
108     write!(cs, "{}", 123).unwrap();
109     expect_eq!(s, "abc123");
110     expect_eq!(cs, "abc123");
111 }
112 
113