use crate::asm::data::literal::Addr;

#[derive(Debug, Clone, Copy)]
pub struct MemorySpan {
    addr: usize,
    len: usize,
}

impl MemorySpan {
    pub fn new(addr: Addr, len: usize) -> MemorySpan {
        if len == 0 {
            panic!("Cannot create empty span!");
        }

        Self {
            addr: addr.0 as usize,
            len,
        }
    }

    /// Get start address
    pub fn start(&self) -> Addr {
        Addr(self.addr as u64)
    }

    /// Get end address (last included byte)
    pub fn last(&self) -> Addr {
        Addr((self.addr + self.len - 1) as u64)
    }

    /// Check if this intersects another span
    pub fn intersects(&self, other: MemorySpan) -> bool {
        !(
            self.last() < other.start()
                || self.start() > other.last()
        )
    }

    /// Check if this is a strict subset of another span
    pub fn inside(&self, other: MemorySpan) -> bool {
        self.start() >= other.start()
            && self.last() <= other.last()
    }
}