disasm-core 0.5.1

Core crate for disasm library
Documentation
use crate::printer::PrinterExt;

#[derive(Clone, Default)]
pub struct Symbols {
    sorted: bool,
    list: Vec<(u64, String)>,
}

impl Symbols {
    pub fn push<S: Into<String>>(&mut self, address: u64, name: S) {
        self.sorted = false;
        self.list.push((address, name.into()));
    }

    pub fn as_slice(&self) -> &[(u64, String)] {
        &self.list
    }

    pub fn as_info(&mut self) -> SymbolsInfo {
        if !self.sorted {
            self.list.sort_by_key(|(addr, _)| *addr);
            self.sorted = true;
        }
        SymbolsInfo { list: &self.list }
    }
}

pub struct SymbolsInfo<'a> {
    list: &'a [(u64, String)],
}

impl PrinterExt for SymbolsInfo<'_> {
    fn get_symbol(&self, address: u64) -> Option<(u64, &str)> {
        let index = match self.list.binary_search_by_key(&address, |(addr, _)| *addr) {
            Ok(index) => index,
            Err(index) => index.checked_sub(1)?,
        };
        self.list
            .get(index)
            .map(|(addr, name)| (*addr, name.as_str()))
    }

    fn get_symbol_after(&self, address: u64) -> Option<(u64, &str)> {
        let symbol = match self.list.binary_search_by_key(&address, |(addr, _)| *addr) {
            Ok(index) => self
                .list
                .iter()
                .skip(index)
                .find(|(addr, _)| *addr != address),
            Err(index) => self.list.get(index),
        };
        symbol.map(|(addr, name)| (*addr, name.as_str()))
    }
}