use lief_ffi as ffi;
use crate::common::{FromFFI, into_optional};
use crate::generic;
use std::marker::PhantomData;
use std::path::Path;
use super::PublicSymbol;
use super::compilation_unit::CompilationUnits;
use super::public_symbol::PublicSymbols;
use super::types::{Type, Types};
pub struct DebugInfo<'a> {
ptr: cxx::UniquePtr<ffi::PDB_DebugInfo>,
_owner: PhantomData<&'a ()>,
}
impl FromFFI<ffi::PDB_DebugInfo> for DebugInfo<'_> {
fn from_ffi(info: cxx::UniquePtr<ffi::PDB_DebugInfo>) -> Self {
Self {
ptr: info,
_owner: PhantomData,
}
}
}
impl DebugInfo<'_> {
pub fn from<P: AsRef<Path>>(path: P) -> Option<DebugInfo<'static>> {
cxx::let_cxx_string!(__cxx_s = path.as_ref().to_str().unwrap());
into_optional(ffi::PDB_DebugInfo::from_file(&__cxx_s))
}
pub fn age(&self) -> u32 {
self.ptr.age()
}
pub fn guid(&self) -> String {
self.ptr.guid().to_string()
}
pub fn compilation_units(&self) -> CompilationUnits<'_> {
CompilationUnits::new(self.ptr.compilation_units())
}
pub fn public_symbols(&self) -> PublicSymbols<'_> {
PublicSymbols::new(self.ptr.public_symbols())
}
pub fn public_symbol_by_name(&self, name: &str) -> Option<PublicSymbol<'_>> {
cxx::let_cxx_string!(__cxx_s = name);
into_optional(self.ptr.public_symbol_by_name(&__cxx_s))
}
pub fn types(&self) -> Types<'_> {
Types::new(self.ptr.types())
}
pub fn type_by_name(&self, name: &str) -> Option<Type<'_>> {
cxx::let_cxx_string!(__cxx_s = name);
into_optional(self.ptr.find_type(&__cxx_s))
}
pub fn type_by_index(&self, index: u32) -> Option<Type<'_>> {
into_optional(self.ptr.find_type_by_index(index))
}
}
impl generic::DebugInfo for DebugInfo<'_> {
fn as_generic(&self) -> &ffi::AbstracDebugInfo {
self.ptr.as_ref().unwrap().as_ref()
}
}
impl std::fmt::Display for DebugInfo<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.ptr.to_string())
}
}