Bug 1293362 - Part 8: Add some tests for using xpcom interfaces from rust code, r=froydnj
authorNika Layzell <nika@thelayzells.com>
Thu, 04 Jan 2018 17:38:05 -0500
changeset 400579 129011c684787bc5be85fd2c971a4edddbf65f5f
parent 400578 8365c868dd1dc7158eb7c1deaf86d877aa127f8a
child 400580 e9724b1b77c3aa4afd26dff17ddf34eb4a4bd55f
push id33311
push usernbeleuzu@mozilla.com
push dateWed, 24 Jan 2018 21:56:54 +0000
treeherdermozilla-central@32b850fa28ae [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1293362
milestone60.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1293362 - Part 8: Add some tests for using xpcom interfaces from rust code, r=froydnj MozReview-Commit-ID: 1b6tfHtyDWf
xpcom/rust/gtest/moz.build
xpcom/rust/gtest/xpcom/Test.cpp
xpcom/rust/gtest/xpcom/test.rs
--- a/xpcom/rust/gtest/moz.build
+++ b/xpcom/rust/gtest/moz.build
@@ -1,11 +1,12 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 UNIFIED_SOURCES += [
     'nsstring/Test.cpp',
+    'xpcom/Test.cpp',
 ]
 
 FINAL_LIBRARY = 'xul-gtest'
new file mode 100644
--- /dev/null
+++ b/xpcom/rust/gtest/xpcom/Test.cpp
@@ -0,0 +1,33 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+#include "nsCOMPtr.h"
+#include "nsIRunnable.h"
+#include "mozilla/Services.h"
+#include "nsIIOService.h"
+
+extern "C" nsIIOService* Rust_CallIURIFromRust();
+
+TEST(RustXpcom, CallIURIFromRust)
+{
+  nsCOMPtr<nsIIOService> rust = Rust_CallIURIFromRust();
+  nsCOMPtr<nsIIOService> cpp = mozilla::services::GetIOService();
+  EXPECT_EQ(rust, cpp);
+}
+
+extern "C" void Rust_ImplementRunnableInRust(bool* aItWorked,
+                                             nsIRunnable** aRunnable);
+
+TEST(RustXpcom, ImplementRunnableInRust)
+{
+  bool itWorked = false;
+  nsCOMPtr<nsIRunnable> runnable;
+  Rust_ImplementRunnableInRust(&itWorked, getter_AddRefs(runnable));
+
+  EXPECT_TRUE(runnable);
+  EXPECT_FALSE(itWorked);
+  runnable->Run();
+  EXPECT_TRUE(itWorked);
+}
--- a/xpcom/rust/gtest/xpcom/test.rs
+++ b/xpcom/rust/gtest/xpcom/test.rs
@@ -5,8 +5,55 @@
 #![allow(non_snake_case)]
 
 #[macro_use]
 extern crate xpcom;
 
 extern crate nserror;
 
 extern crate nsstring;
+
+use std::ptr;
+use xpcom::{XpCom, getter_addrefs, interfaces};
+use nserror::{NsresultExt, nsresult, NS_OK};
+use nsstring::{nsCStr, nsCString};
+
+#[no_mangle]
+pub unsafe extern fn Rust_CallIURIFromRust() -> *const interfaces::nsIIOService {
+    let iosvc = xpcom::services::get_IOService().unwrap();
+
+    let uri = getter_addrefs(|p| iosvc.NewURI(&nsCStr::from("https://google.com"), ptr::null(), ptr::null(), p)).unwrap();
+
+    let mut host = nsCString::new();
+    let rv = uri.GetHost(&mut host);
+    assert!(rv.succeeded());
+
+    assert_eq!(&*host, "google.com");
+
+    assert!(iosvc.query_interface::<interfaces::nsISupports>().is_some());
+    assert!(iosvc.query_interface::<interfaces::nsIURI>().is_none());
+    &*iosvc
+}
+
+#[no_mangle]
+pub unsafe extern fn Rust_ImplementRunnableInRust(it_worked: *mut bool,
+                                                  runnable: *mut *const interfaces::nsIRunnable) {
+    // Define a type which implements nsIRunnable in rust.
+    #[derive(xpcom)]
+    #[xpimplements(nsIRunnable)]
+    #[refcnt = "atomic"]
+    struct InitMyRunnable {
+        it_worked: *mut bool,
+    }
+
+    impl MyRunnable {
+        unsafe fn Run(&self) -> nsresult {
+            *self.it_worked = true;
+            NS_OK
+        }
+    }
+
+    // Create my runnable type, and forget it into the outparameter!
+    let my_runnable = MyRunnable::allocate(InitMyRunnable {
+        it_worked: it_worked
+    });
+    my_runnable.query_interface::<interfaces::nsIRunnable>().unwrap().forget(&mut *runnable);
+}