use stet_core::context::Context;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ExecWarning {
pub kind: ExecWarningKind,
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum ExecWarningKind {
DroppedFinalPage {
objects: usize,
pages_emitted: i32,
},
}
impl ExecWarning {
pub fn hint(&self) -> &'static str {
match self.kind {
ExecWarningKind::DroppedFinalPage { .. } => {
"Append `showpage` to the program, or mark it as EPS (an `EPSF` header line \
or a `.eps` extension) to have stet emit the final page implicitly."
}
}
}
}
impl std::fmt::Display for ExecWarning {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.kind {
ExecWarningKind::DroppedFinalPage {
objects,
pages_emitted,
} => {
write!(
f,
"painted {} object(s) and then ended without a matching `showpage`, so ",
objects
)?;
if pages_emitted == 0 {
write!(f, "no page was output")
} else {
write!(
f,
"that page was dropped ({} earlier page(s) were output)",
pages_emitted
)
}
}
}
}
}
pub fn dropped_final_page(ctx: &Context) -> Option<ExecWarning> {
if ctx.display_list.is_empty() {
return None;
}
if ctx.null_device_used {
return None;
}
Some(ExecWarning {
kind: ExecWarningKind::DroppedFinalPage {
objects: ctx.display_list.len(),
pages_emitted: stet_ops::device_ops::get_pd_int(ctx, b"PageCount").unwrap_or(0),
},
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn message_names_total_loss_when_no_pages_came_out() {
let w = ExecWarning {
kind: ExecWarningKind::DroppedFinalPage {
objects: 8,
pages_emitted: 0,
},
};
assert_eq!(
w.to_string(),
"painted 8 object(s) and then ended without a matching `showpage`, \
so no page was output"
);
}
#[test]
fn message_names_partial_loss_when_earlier_pages_came_out() {
let w = ExecWarning {
kind: ExecWarningKind::DroppedFinalPage {
objects: 1,
pages_emitted: 5,
},
};
assert_eq!(
w.to_string(),
"painted 1 object(s) and then ended without a matching `showpage`, \
so that page was dropped (5 earlier page(s) were output)"
);
}
#[test]
fn hint_points_at_both_remedies() {
let w = ExecWarning {
kind: ExecWarningKind::DroppedFinalPage {
objects: 1,
pages_emitted: 0,
},
};
assert!(w.hint().contains("showpage"));
assert!(w.hint().contains(".eps"));
}
}