use std::sync::OnceLock;
use thiserror::Error;
use crate::catalog::{Catalog, CatalogProfile};
use crate::definition::CatalogEdition;
use crate::overlay::{corrected_patches, PatchError};
use crate::snapshot::{decode_edition, ArchiveError};
pub(crate) const CONTAINER: &[u8] = include_bytes!("../data/catalog.bin");
static IFC2X3_TC1: OnceLock<Result<Catalog, ArchiveError>> = OnceLock::new();
static IFC4_ADD2_TC1: OnceLock<Result<Catalog, ArchiveError>> = OnceLock::new();
static IFC4X3_ADD2: OnceLock<Result<Catalog, ArchiveError>> = OnceLock::new();
static IFC4_ADD2_TC1_CORRECTED: OnceLock<Result<Catalog, EmbeddedCatalogError>> = OnceLock::new();
static IFC4X3_ADD2_CORRECTED: OnceLock<Result<Catalog, EmbeddedCatalogError>> = OnceLock::new();
pub fn load_catalog(
edition: CatalogEdition,
profile: CatalogProfile,
) -> Result<Catalog, EmbeddedCatalogError> {
match profile {
CatalogProfile::Official => official_catalog(edition),
CatalogProfile::Corrected => corrected_catalog(edition),
_ => Err(EmbeddedCatalogError::UnsupportedProfile(profile)),
}
}
pub fn official_catalog(edition: CatalogEdition) -> Result<Catalog, EmbeddedCatalogError> {
let slot = match edition {
CatalogEdition::Ifc2x3Tc1 => &IFC2X3_TC1,
CatalogEdition::Ifc4Add2Tc1 => &IFC4_ADD2_TC1,
CatalogEdition::Ifc4x3Add2 => &IFC4X3_ADD2,
};
slot.get_or_init(|| decode_edition(CONTAINER, edition))
.clone()
.map_err(EmbeddedCatalogError::Archive)
}
pub fn corrected_catalog(edition: CatalogEdition) -> Result<Catalog, EmbeddedCatalogError> {
let slot = match edition {
CatalogEdition::Ifc4Add2Tc1 => &IFC4_ADD2_TC1_CORRECTED,
CatalogEdition::Ifc4x3Add2 => &IFC4X3_ADD2_CORRECTED,
_ => return Err(EmbeddedCatalogError::UnavailableEdition(edition)),
};
slot.get_or_init(|| {
let official = official_catalog(edition)?;
official
.with_patches(CatalogProfile::Corrected, &corrected_patches(edition))
.map_err(EmbeddedCatalogError::Patch)
})
.clone()
}
#[derive(Debug, Clone, PartialEq, Eq, Error)]
#[non_exhaustive]
pub enum EmbeddedCatalogError {
#[error("no embedded catalog for {0:?}")]
UnavailableEdition(CatalogEdition),
#[error("embedded loading does not construct {0:?} profiles")]
UnsupportedProfile(CatalogProfile),
#[error(transparent)]
Archive(#[from] ArchiveError),
#[error(transparent)]
Patch(#[from] PatchError),
}