use core::fmt;
use hir_lang::UnitId;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Limit {
GlobBindings,
MemberSteps,
}
impl Limit {
#[must_use]
pub const fn name(self) -> &'static str {
match self {
Self::GlobBindings => "glob bindings",
Self::MemberSteps => "member lookup steps",
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum ResolveError {
BudgetExceeded {
limit: Limit,
},
DuplicateUnit {
unit: UnitId,
},
}
impl fmt::Display for ResolveError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::BudgetExceeded { limit } => {
write!(f, "resolution exceeded its budget of {}", limit.name())
}
Self::DuplicateUnit { unit } => {
write!(f, "two units of the program have the id {}", unit.as_u32())
}
}
}
}
impl core::error::Error for ResolveError {}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Budget {
glob_bindings: u64,
member_steps: u64,
suggestion_cells: u64,
}
impl Default for Budget {
fn default() -> Self {
Self {
glob_bindings: 16_000_000,
member_steps: 16_000_000,
suggestion_cells: 32_000_000,
}
}
}
impl Budget {
#[must_use]
pub const fn unlimited() -> Self {
Self {
glob_bindings: u64::MAX,
member_steps: u64::MAX,
suggestion_cells: u64::MAX,
}
}
#[must_use]
pub const fn with_glob_bindings(mut self, n: u64) -> Self {
self.glob_bindings = n;
self
}
#[must_use]
pub const fn with_member_steps(mut self, n: u64) -> Self {
self.member_steps = n;
self
}
#[must_use]
pub const fn with_suggestion_cells(mut self, n: u64) -> Self {
self.suggestion_cells = n;
self
}
#[must_use]
pub const fn glob_bindings(&self) -> u64 {
self.glob_bindings
}
#[must_use]
pub const fn member_steps(&self) -> u64 {
self.member_steps
}
#[must_use]
pub const fn suggestion_cells(&self) -> u64 {
self.suggestion_cells
}
}