use crate::platform::Launcher;
use crate::policy::{self, Notify};
use crate::present::{Channel, Report, Weight};
#[derive(Clone, Copy)]
pub struct Outside<'a> {
pub policy: &'a dyn policy::Source,
pub launcher: &'a dyn Launcher,
pub channel: &'a dyn Channel,
pub notify: Notify,
}
impl<'a> Outside<'a> {
#[must_use]
pub fn new(
policy: &'a dyn policy::Source,
launcher: &'a dyn Launcher,
channel: &'a dyn Channel,
) -> Self {
Self {
policy,
launcher,
channel,
notify: Notify::default(),
}
}
#[must_use]
pub fn saying(mut self, notify: Notify) -> Self {
self.notify = notify;
self
}
pub fn report(&self, report: &Report) {
if report.weight != Weight::Routine || self.notify == Notify::Everything {
self.channel.report(report);
}
}
}
#[cfg(test)]
mod tests {
use super::Outside;
use crate::platform::testing::Recording as Launching;
use crate::policy::{Notify, Origin, Read, Source};
use crate::present::testing::Recording as Told;
use crate::present::{Choice, Question, Report};
struct Default_;
impl Source for Default_ {
fn layer(&self, _o: Origin) -> Read {
Ok(None)
}
}
fn three() -> [Report; 3] {
[
Report::routine("a save landed"),
Report::ordinary("you asked and here is the answer"),
Report::interrupt("this one is a warning"),
]
}
#[test]
fn the_default_drops_what_happened_on_its_own_and_nothing_else() {
let launcher = Launching::default();
let told = Told::default();
let outside = Outside::new(&Default_, &launcher, &told);
assert_eq!(outside.notify, Notify::Important);
for r in &three() {
outside.report(r);
}
let said = told.said();
assert!(!said.contains("a save landed"), "{said}");
assert!(said.contains("you asked"), "{said}");
assert!(said.contains("a warning"), "{said}");
}
#[test]
fn saying_everything_lets_the_routine_ones_through() {
let launcher = Launching::default();
let told = Told::default();
let outside = Outside::new(&Default_, &launcher, &told).saying(Notify::Everything);
for r in &three() {
outside.report(r);
}
assert_eq!(told.reports().len(), 3);
}
#[test]
fn no_setting_can_silence_a_question() {
let launcher = Launching::default();
let told = Told::default();
let outside = Outside::new(&Default_, &launcher, &told);
outside.channel.ask(&Question {
about: "abc-0".into(),
summary: "report.pdf was left behind.".into(),
detail: Vec::new(),
choices: vec![Choice::WriteBack, Choice::Discard],
});
assert_eq!(told.questions().len(), 1);
}
}