Source code

Revision control

Copy as Markdown

Other Tools

// 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 https://mozilla.org/MPL/2.0/.
use std::sync::LazyLock;
#[doc(hidden)]
pub extern crate serde as __serde;
#[doc(hidden)]
pub mod __serde_helper {
/// Deserialize value to a `Vec<T>`.
///
/// If the value was `null` return an empty vector.
pub fn vec_null<'de, D: serde::Deserializer<'de>, T: serde::Deserialize<'de>>(
d: D,
) -> Result<Vec<T>, D::Error> {
let res: Option<Vec<T>> = serde::Deserialize::deserialize(d)?;
Ok(res.unwrap_or_default())
}
}
// Re-export types that are used by the glean_parser-generated code.
#[doc(hidden)]
pub mod __export {
pub use once_cell::sync::Lazy;
}
const FFI_CONTRACT_VERSION: u32 = include!("contract_version.txt");
macro_rules! library_binding {
( $localname:ident members[$($members:tt)*] load[$($load:tt)*] fn $name:ident $args:tt $( -> $ret:ty )? ; $($rest:tt)* ) => {
library_binding! {
$localname
members[
$($members)*
pub(crate) $name: libloading::Symbol<'static, unsafe extern "C" fn $args $(->$ret)?>,
]
load[
$($load)*
$name: unsafe {
let symbol = $localname.get::<unsafe extern "C" fn $args $(->$ret)?>(stringify!($name).as_bytes())
.map_err(|e| std::io::Error::new(std::io::ErrorKind::NotFound, e))?;
// All symbols refer to library, so `'static` lifetimes are safe (`library`
// will outlive them).
std::mem::transmute::<_, libloading::Symbol<'static, _>>(symbol)
},
]
$($rest)*
}
};
( $localname:ident members[$($members:tt)*] load[$($load:tt)*] ) => {
pub struct GleanSym {
$($members)*
_library: libloading::Library,
}
impl GleanSym {
#[cfg(all(unix, not(target_os = "ios")))]
pub fn load() -> std::io::Result<Self> {
let name = libloading::library_filename("xul");
let library = match unsafe { libloading::Library::new(name) } {
Ok(lib) => Some(lib),
Err(_e) => None,
};
let $localname = library.ok_or_else(|| {
std::io::Error::new(std::io::ErrorKind::NotFound, "failed to find glean library")
})?;
let handle = GleanSym { $($load)* _library: $localname };
handle.check()?;
Ok(handle)
}
#[cfg(target_os = "ios")]
pub fn load() -> std::io::Result<Self> {
// On iOS we compile it all together and can look up symbols without loading a library
let $localname: libloading::Library = libloading::os::unix::Library::this().into();
Ok(GleanSym { $($load)* _library: $localname })
}
#[cfg(not(unix))]
pub fn load() -> std::io::Result<Self> {
compile_error!("This crate is not implemented for Windows");
}
fn check(&self) -> std::io::Result<()> {
let ffi_contract_version = unsafe { (self.ffi_glean_core_uniffi_contract_version)() };
if crate::FFI_CONTRACT_VERSION == ffi_contract_version {
Ok(())
} else {
Err(std::io::Error::other("contract version mismatch"))
}
}
}
};
( $($rest:tt)* ) => {
library_binding! {
library members[] load[] $($rest)*
}
}
}
pub mod metrics;
pub mod types;
mod util;
static GLEAN: LazyLock<metrics::GleanSym> = LazyLock::new(|| metrics::GleanSym::load().unwrap());
// This boilerplate is usually generated by `uniffi::setup_scaffolding!()`
// along with all the extra FFI functions, like wrappers around Rust buffer allocation, async handling, etc.
// We don't want to export those, so we do only the minimal part to support what `glean-sym` calls when used in other
// crates.
/// The crate-specific tag to implement traits.
#[doc(hidden)]
pub struct UniFfiTag;
/// The namespace glean-sym FFI items are placed in.
/// Required by UniFFI to match up items.
const UNIFFI_META_CONST_NAMESPACE_GLEAN_SYM: ::uniffi::MetadataBuffer =
::uniffi::MetadataBuffer::from_code(::uniffi::metadata::codes::NAMESPACE)
.concat_str("glean_sym")
.concat_str("glean_sym");
#[doc(hidden)]
#[unsafe(no_mangle)]
pub static UNIFFI_META_NAMESPACE_GLEAN_SYM: [::std::primitive::u8;
UNIFFI_META_CONST_NAMESPACE_GLEAN_SYM.size] =
UNIFFI_META_CONST_NAMESPACE_GLEAN_SYM.into_array();