use crate::catalog::{Catalog, Kind};
use crate::core::error::{Result, WorkshopError};
use crate::wir;
pub(crate) fn validate_event(
event: &wir::Event,
span: Option<crate::core::source::Span>,
catalog: &Catalog,
) -> Result<()> {
let (id, filters) = match event {
wir::Event::Global => ("global", None),
wir::Event::EachPlayer => ("eachPlayer", None),
wir::Event::EachPlayerWithFilters { team, target } => ("eachPlayer", Some((*team, target))),
wir::Event::Player { kind, team, target } => (kind.catalog_id(), Some((*team, target))),
wir::Event::Subroutine { .. } => ("subroutine", None),
};
if catalog.entry(Kind::Event, id).is_none() {
return Err(WorkshopError::unknown(
"event",
id.to_string(),
crate::catalog::Locale::new("en-US"),
span,
)
.with_candidates(crate::core::suggest::nearest(
id,
catalog.canonical_spellings(Kind::Event, catalog.primary_locale()),
crate::core::suggest::CANDIDATE_LIMIT,
)));
}
let Some((team, target)) = filters else {
return Ok(());
};
let en = crate::catalog::Locale::new("en-US");
let team_member = match team {
wir::EventTeam::All => "ALL",
wir::EventTeam::Team1 => "TEAM_1",
wir::EventTeam::Team2 => "TEAM_2",
};
if catalog
.enum_spelling("EventTeam", &en, team_member)
.is_none()
{
return Err(WorkshopError::unknown(
"event team",
team_member.to_string(),
en.clone(),
span,
)
.with_candidates(crate::core::suggest::nearest(
team_member,
catalog.canonical_member_spellings("EventTeam", catalog.primary_locale()),
crate::core::suggest::CANDIDATE_LIMIT,
)));
}
let target_member = match target {
wir::EventTarget::All => Some("ALL".to_string()),
wir::EventTarget::Slot(slot) => Some(format!("SLOT_{slot}")),
wir::EventTarget::Hero(hero) => {
if catalog.enum_spelling("Hero", &en, hero).is_none() {
return Err(
WorkshopError::unknown("event player", hero.clone(), en.clone(), span)
.with_candidates(crate::core::suggest::nearest(
hero,
catalog
.canonical_member_spellings("EventPlayer", catalog.primary_locale())
.chain(
catalog.canonical_member_spellings(
"Hero",
catalog.primary_locale(),
),
),
crate::core::suggest::CANDIDATE_LIMIT,
)),
);
}
None
}
};
if let Some(target_member) = target_member {
if catalog
.enum_spelling("EventPlayer", &en, &target_member)
.is_none()
{
return Err(
WorkshopError::unknown("event player", target_member.clone(), en, span)
.with_candidates(crate::core::suggest::nearest(
&target_member,
catalog
.canonical_member_spellings("EventPlayer", catalog.primary_locale())
.chain(
catalog
.canonical_member_spellings("Hero", catalog.primary_locale()),
),
crate::core::suggest::CANDIDATE_LIMIT,
)),
);
}
}
Ok(())
}