use std::path::PathBuf;
use crate::symbolize::Sym;
use super::buildid::BuildId;
#[cfg(doc)]
use super::NormalizeOpts;
use super::Reason;
cfg_apk! {
#[derive(Clone, Debug, PartialEq)]
pub struct Apk {
pub path: PathBuf,
#[doc(hidden)]
pub _non_exhaustive: (),
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct Elf<'src> {
pub path: PathBuf,
pub build_id: Option<BuildId<'src>>,
#[doc(hidden)]
pub _non_exhaustive: (),
}
#[derive(Clone, Debug, PartialEq)]
pub struct Unknown {
pub reason: Reason,
#[doc(hidden)]
pub _non_exhaustive: (),
}
impl Unknown {
#[inline]
pub(crate) fn new(reason: Reason) -> Self {
Self {
reason,
_non_exhaustive: (),
}
}
}
impl From<Unknown> for UserMeta<'_> {
fn from(unknown: Unknown) -> Self {
Self::Unknown(unknown)
}
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum UserMeta<'src> {
#[cfg(feature = "apk")]
#[cfg_attr(docsrs, doc(cfg(feature = "apk")))]
Apk(Apk),
Elf(Elf<'src>),
Sym(Sym<'src>),
Unknown(Unknown),
}
impl<'src> UserMeta<'src> {
#[cfg(feature = "apk")]
#[cfg_attr(docsrs, doc(cfg(feature = "apk")))]
#[inline]
pub fn as_apk(&self) -> Option<&Apk> {
match self {
Self::Apk(entry) => Some(entry),
_ => None,
}
}
#[inline]
pub fn as_elf(&self) -> Option<&Elf<'src>> {
match self {
Self::Elf(elf) => Some(elf),
_ => None,
}
}
#[inline]
pub fn as_sym(&self) -> Option<&Sym<'src>> {
match self {
Self::Sym(sym) => Some(sym),
_ => None,
}
}
#[inline]
pub fn as_unknown(&self) -> Option<&Unknown> {
match self {
Self::Unknown(unknown) => Some(unknown),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::borrow::Cow;
#[test]
fn user_addr_meta_accessors() {
let meta = UserMeta::Apk(Apk {
path: PathBuf::from("/tmp/archive.apk"),
_non_exhaustive: (),
});
assert!(meta.as_apk().is_some());
assert!(meta.as_elf().is_none());
assert!(meta.as_sym().is_none());
assert!(meta.as_unknown().is_none());
let meta = UserMeta::Elf(Elf {
path: PathBuf::from("/tmp/executable.bin"),
build_id: None,
_non_exhaustive: (),
});
assert!(meta.as_apk().is_none());
assert!(meta.as_elf().is_some());
assert!(meta.as_sym().is_none());
assert!(meta.as_unknown().is_none());
let sym = Sym {
name: Cow::Borrowed("test"),
module: None,
addr: 1337,
offset: 42,
size: None,
code_info: None,
inlined: Box::new([]),
_non_exhaustive: (),
};
let meta = UserMeta::Sym(sym);
assert!(meta.as_apk().is_none());
assert!(meta.as_elf().is_none());
assert!(meta.as_sym().is_some());
assert!(meta.as_unknown().is_none());
let meta = UserMeta::Unknown(Unknown {
reason: Reason::Unsupported,
_non_exhaustive: (),
});
assert!(meta.as_apk().is_none());
assert!(meta.as_elf().is_none());
assert!(meta.as_sym().is_none());
assert!(meta.as_unknown().is_some());
}
}