use std::error::Error;
use std::fmt::{Display, Formatter};

use crate::components::address::Address;

/// The struct used for errors when converting instructions to binary.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AssemblyError {
    /// The description for the error.
    pub description: String,
    /// The specific address of the error.
    pub address: Option<Address>
}

impl AssemblyError {
    pub(crate) fn new(description: String, address: Option<Address>) -> Self {
        Self { description, address }
    }
}

impl Display for AssemblyError {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        if let Some(address) = self.address {
            write!(f, "[Address {}] ", address.0)?;
        }
        write!(f, "{}", self.description)
    }
}

impl Error for AssemblyError {}
