use std::borrow::Cow;
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct ExportSpec<'a> {
pub name: Cow<'a, [u8]>,
pub internal_name: Option<Cow<'a, [u8]>>,
pub import_name: Option<Cow<'a, [u8]>>,
pub export_as: Option<Cow<'a, [u8]>>,
pub ordinal: Option<u16>,
pub noname: bool,
pub data: bool,
pub private: bool,
pub constant: bool,
}
impl ExportSpec<'_> {
#[must_use]
pub fn forwarder(&self) -> Option<&[u8]> {
self.internal_name
.as_deref()
.filter(|internal| internal.contains(&b'.'))
}
#[must_use]
pub fn symbol(&self) -> Option<&[u8]> {
if self.forwarder().is_some() {
return None;
}
Some(self.internal_name.as_deref().unwrap_or(&self.name))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn symbol_and_forwarder() {
let mut spec = ExportSpec {
name: Cow::Borrowed(b"foo"),
..ExportSpec::default()
};
assert_eq!(spec.symbol(), Some(&b"foo"[..]));
spec.internal_name = Some(Cow::Borrowed(b"bar"));
assert_eq!(spec.symbol(), Some(&b"bar"[..]));
assert_eq!(spec.forwarder(), None);
spec.internal_name = Some(Cow::Borrowed(b"kernel32.Sleep"));
assert_eq!(spec.symbol(), None);
assert_eq!(spec.forwarder(), Some(&b"kernel32.Sleep"[..]));
}
}