use std::collections::BTreeSet;
use serde::{Deserialize, Serialize};
use crate::model::symbol::SymbolKind;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[serde(rename_all = "snake_case")]
pub enum ResolverClass {
Macro,
Include,
Behaviour,
QualifiedCall,
Record,
LocalCall,
Type,
IndirectCall,
}
impl ResolverClass {
#[must_use]
pub fn as_str(self) -> &'static str {
match self {
ResolverClass::Macro => "macro",
ResolverClass::Include => "include",
ResolverClass::Behaviour => "behaviour",
ResolverClass::QualifiedCall => "qualified_call",
ResolverClass::Record => "record",
ResolverClass::LocalCall => "local_call",
ResolverClass::Type => "type",
ResolverClass::IndirectCall => "indirect_call",
}
}
pub const ALL: [ResolverClass; 8] = [
ResolverClass::Macro,
ResolverClass::Include,
ResolverClass::Behaviour,
ResolverClass::QualifiedCall,
ResolverClass::Record,
ResolverClass::LocalCall,
ResolverClass::Type,
ResolverClass::IndirectCall,
];
#[must_use]
pub fn is_covered(self) -> bool {
match self {
ResolverClass::Macro
| ResolverClass::Include
| ResolverClass::Behaviour
| ResolverClass::QualifiedCall
| ResolverClass::Record
| ResolverClass::LocalCall
| ResolverClass::Type
| ResolverClass::IndirectCall => true,
}
}
#[must_use]
pub fn of_symbol_kind(kind: &SymbolKind) -> ResolverClass {
match kind {
SymbolKind::Macro { .. } => ResolverClass::Macro,
SymbolKind::Record { .. } => ResolverClass::Record,
SymbolKind::Behaviour { .. } | SymbolKind::Callback { .. } => ResolverClass::Behaviour,
SymbolKind::Type { .. } => ResolverClass::Type,
SymbolKind::Function { .. } | SymbolKind::FunctionAnyArity { .. } => {
ResolverClass::QualifiedCall
}
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct ResolverCoverage {
checked: BTreeSet<ResolverClass>,
}
impl ResolverCoverage {
#[must_use]
pub fn current() -> Self {
Self {
checked: ResolverClass::ALL
.into_iter()
.filter(|c| c.is_covered())
.collect(),
}
}
#[must_use]
pub fn is_checked(&self, class: ResolverClass) -> bool {
self.checked.contains(&class)
}
pub fn unchecked(&self) -> impl Iterator<Item = ResolverClass> + '_ {
ResolverClass::ALL
.into_iter()
.filter(|c| !self.checked.contains(c))
}
}