summaryrefslogtreecommitdiffstats
path: root/xpcom/rust/xpcom/src/statics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'xpcom/rust/xpcom/src/statics.rs')
-rw-r--r--xpcom/rust/xpcom/src/statics.rs75
1 files changed, 75 insertions, 0 deletions
diff --git a/xpcom/rust/xpcom/src/statics.rs b/xpcom/rust/xpcom/src/statics.rs
new file mode 100644
index 0000000000..27f66fdb4b
--- /dev/null
+++ b/xpcom/rust/xpcom/src/statics.rs
@@ -0,0 +1,75 @@
+/* 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/. */
+
+use crate::interfaces::{nsIComponentManager, nsIComponentRegistrar, nsIServiceManager};
+use crate::{GetterAddrefs, RefPtr, XpCom};
+use std::ffi::CStr;
+
+/// Get a reference to the global `nsIComponentManager`.
+///
+/// Can return `None` during shutdown.
+#[inline]
+pub fn component_manager() -> Option<RefPtr<nsIComponentManager>> {
+ unsafe { RefPtr::from_raw(Gecko_GetComponentManager()) }
+}
+
+/// Get a reference to the global `nsIServiceManager`.
+///
+/// Can return `None` during shutdown.
+#[inline]
+pub fn service_manager() -> Option<RefPtr<nsIServiceManager>> {
+ unsafe { RefPtr::from_raw(Gecko_GetServiceManager()) }
+}
+
+/// Get a reference to the global `nsIComponentRegistrar`
+///
+/// Can return `None` during shutdown.
+#[inline]
+pub fn component_registrar() -> Option<RefPtr<nsIComponentRegistrar>> {
+ unsafe { RefPtr::from_raw(Gecko_GetComponentRegistrar()) }
+}
+
+/// Helper for calling `nsIComponentManager::CreateInstanceByContractID` on the
+/// global `nsIComponentRegistrar`.
+///
+/// This method is similar to `do_CreateInstance` in C++.
+#[inline]
+pub fn create_instance<T: XpCom>(id: &CStr) -> Option<RefPtr<T>> {
+ unsafe {
+ let mut ga = GetterAddrefs::<T>::new();
+ if component_manager()?
+ .CreateInstanceByContractID(id.as_ptr(), &T::IID, ga.void_ptr())
+ .succeeded()
+ {
+ ga.refptr()
+ } else {
+ None
+ }
+ }
+}
+
+/// Helper for calling `nsIServiceManager::GetServiceByContractID` on the global
+/// `nsIServiceManager`.
+///
+/// This method is similar to `do_GetService` in C++.
+#[inline]
+pub fn get_service<T: XpCom>(id: &CStr) -> Option<RefPtr<T>> {
+ unsafe {
+ let mut ga = GetterAddrefs::<T>::new();
+ if service_manager()?
+ .GetServiceByContractID(id.as_ptr(), &T::IID, ga.void_ptr())
+ .succeeded()
+ {
+ ga.refptr()
+ } else {
+ None
+ }
+ }
+}
+
+extern "C" {
+ fn Gecko_GetComponentManager() -> *const nsIComponentManager;
+ fn Gecko_GetServiceManager() -> *const nsIServiceManager;
+ fn Gecko_GetComponentRegistrar() -> *const nsIComponentRegistrar;
+}