use crate::document::Model;
use crate::report::loss::LossNote;
use crate::schema::{EntityKind, EntitySchema};
use super::loss::ExportLossCode;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ArenaDisposition {
Written,
Reported,
Omitted,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ArenaCoverage {
Complete,
Declared(ArenaDispositions),
}
impl ArenaCoverage {
pub(super) fn omission_losses(&self, model: &Model, format: &str) -> Vec<LossNote> {
match self {
Self::Complete => Vec::new(),
Self::Declared(dispositions) => dispositions.omission_losses(model, format),
}
}
}
fn arena_kind<T: EntitySchema>(_: &[T]) -> EntityKind {
T::KIND
}
macro_rules! declare_arena_dispositions {
($($field:ident: $ty:ty, $doc:literal, [$($attribute:meta),*] $(, [$($schema_attr:meta),*])?;)*) => {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ArenaDispositions {
$(
#[doc = concat!("Disposition of the `", stringify!($field), "` arena.")]
pub $field: ArenaDisposition,
)*
}
impl ArenaDispositions {
fn omission_losses(&self, model: &Model, format: &str) -> Vec<LossNote> {
let mut losses = Vec::new();
$(
if self.$field == ArenaDisposition::Omitted && !model.$field.is_empty() {
losses.push(
ExportLossCode::ArenaOmitted(arena_kind(&model.$field))
.note(format!(
"the {format} write does not represent model arena `{}`: \
{} record(s) omitted",
stringify!($field),
model.$field.len(),
)),
);
}
)*
losses
}
}
};
}
crate::document::arena_registry!(declare_arena_dispositions);