summaryrefslogtreecommitdiffstats
path: root/xpcom/rust/xpcom/src/base.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /xpcom/rust/xpcom/src/base.rs
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'xpcom/rust/xpcom/src/base.rs')
-rw-r--r--xpcom/rust/xpcom/src/base.rs59
1 files changed, 59 insertions, 0 deletions
diff --git a/xpcom/rust/xpcom/src/base.rs b/xpcom/rust/xpcom/src/base.rs
new file mode 100644
index 0000000000..556768a179
--- /dev/null
+++ b/xpcom/rust/xpcom/src/base.rs
@@ -0,0 +1,59 @@
+/* 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::{nsIInterfaceRequestor, nsISupports};
+use crate::{GetterAddrefs, RefCounted, RefPtr};
+
+#[repr(C)]
+#[derive(Copy, Clone, Eq, PartialEq)]
+/// A "unique identifier". This is modeled after OSF DCE UUIDs.
+pub struct nsID(pub u32, pub u16, pub u16, pub [u8; 8]);
+
+/// Interface IDs
+pub type nsIID = nsID;
+/// Class IDs
+pub type nsCID = nsID;
+
+/// A type which implements XpCom must follow the following rules:
+///
+/// * It must be a legal XPCOM interface.
+/// * The result of a QueryInterface or similar call, passing IID, must return a
+/// valid reference to an object of the given type.
+/// * It must be valid to cast a &self reference to a &nsISupports reference.
+pub unsafe trait XpCom: RefCounted {
+ const IID: nsIID;
+
+ /// Perform a QueryInterface call on this object, attempting to dynamically
+ /// cast it to the requested interface type. Returns Some(RefPtr<T>) if the
+ /// cast succeeded, and None otherwise.
+ fn query_interface<T: XpCom>(&self) -> Option<RefPtr<T>> {
+ let mut ga = GetterAddrefs::<T>::new();
+ unsafe {
+ if (*(self as *const Self as *const nsISupports))
+ .QueryInterface(&T::IID, ga.void_ptr())
+ .succeeded()
+ {
+ ga.refptr()
+ } else {
+ None
+ }
+ }
+ }
+
+ /// Perform a `GetInterface` call on this object, returning `None` if the
+ /// object doesn't implement `nsIInterfaceRequestor`, or can't access the
+ /// interface `T`.
+ fn get_interface<T: XpCom>(&self) -> Option<RefPtr<T>> {
+ let ireq = self.query_interface::<nsIInterfaceRequestor>()?;
+
+ let mut ga = GetterAddrefs::<T>::new();
+ unsafe {
+ if ireq.GetInterface(&T::IID, ga.void_ptr()).succeeded() {
+ ga.refptr()
+ } else {
+ None
+ }
+ }
+ }
+}