use remain::sorted;
use serde::Deserialize;
use serde::Serialize;
use thiserror::Error;
pub use crate::address_range::AddressRange;
pub use crate::pci_address::Error as PciAddressError;
pub use crate::pci_address::PciAddress;
pub use crate::system_allocator::AllocOptions;
pub use crate::system_allocator::MmioType;
pub use crate::system_allocator::SystemAllocator;
pub use crate::system_allocator::SystemAllocatorConfig;
pub mod address_allocator;
mod address_range;
mod pci_address;
mod system_allocator;
#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone, Serialize, Deserialize)]
pub enum Alloc {
    Anon(usize),
    PciBar { bus: u8, dev: u8, func: u8, bar: u8 },
    GpuRenderNode,
    PmemDevice(usize),
    Pstore,
    PciBridgeWindow { bus: u8, dev: u8, func: u8 },
    PciBridgePrefetchWindow { bus: u8, dev: u8, func: u8 },
    FileBacked(u64),
}
#[sorted]
#[derive(Error, Debug, Eq, PartialEq)]
pub enum Error {
    #[error("Allocation cannot have size of 0")]
    AllocSizeZero,
    #[error("Pool alignment must be a power of 2")]
    BadAlignment,
    #[error("Alloc does not exist: {0:?}")]
    BadAlloc(Alloc),
    #[error("Alloc already exists: {0:?}")]
    ExistingAlloc(Alloc),
    #[error("Invalid Alloc: {0:?}")]
    InvalidAlloc(Alloc),
    #[error("IO port out of range: {0}")]
    IOPortOutOfRange(AddressRange),
    #[error("Platform MMIO address range not specified")]
    MissingPlatformMMIOAddresses,
    #[error("No IO address range specified")]
    NoIoAllocator,
    #[error("Out of bounds")]
    OutOfBounds,
    #[error("Out of space")]
    OutOfSpace,
    #[error("base={base} + size={size} overflows")]
    PoolOverflow { base: u64, size: u64 },
    #[error("Overlapping region {0}")]
    RegionOverlap(AddressRange),
}
pub type Result<T> = std::result::Result<T, Error>;