1use crate::platform::Launcher;
19use crate::policy::{self, Notify};
20use crate::present::{Channel, Report, Weight};
21
22#[derive(Clone, Copy)]
24pub struct Outside<'a> {
25 pub policy: &'a dyn policy::Source,
27 pub launcher: &'a dyn Launcher,
29 pub channel: &'a dyn Channel,
31 pub notify: Notify,
34}
35
36impl<'a> Outside<'a> {
37 #[must_use]
39 pub fn new(
40 policy: &'a dyn policy::Source,
41 launcher: &'a dyn Launcher,
42 channel: &'a dyn Channel,
43 ) -> Self {
44 Self {
45 policy,
46 launcher,
47 channel,
48 notify: Notify::default(),
49 }
50 }
51
52 #[must_use]
54 pub fn saying(mut self, notify: Notify) -> Self {
55 self.notify = notify;
56 self
57 }
58
59 pub fn report(&self, report: &Report) {
65 if report.weight != Weight::Routine || self.notify == Notify::Everything {
66 self.channel.report(report);
67 }
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::Outside;
74 use crate::platform::testing::Recording as Launching;
75 use crate::policy::{Notify, Origin, Read, Source};
76 use crate::present::testing::Recording as Told;
77 use crate::present::{Choice, Question, Report};
78
79 struct Default_;
80 impl Source for Default_ {
81 fn layer(&self, _o: Origin) -> Read {
82 Ok(None)
83 }
84 }
85
86 fn three() -> [Report; 3] {
87 [
88 Report::routine("a save landed"),
89 Report::ordinary("you asked and here is the answer"),
90 Report::interrupt("this one is a warning"),
91 ]
92 }
93
94 #[test]
95 fn the_default_drops_what_happened_on_its_own_and_nothing_else() {
96 let launcher = Launching::default();
97 let told = Told::default();
98 let outside = Outside::new(&Default_, &launcher, &told);
99 assert_eq!(outside.notify, Notify::Important);
100 for r in &three() {
101 outside.report(r);
102 }
103 let said = told.said();
104 assert!(!said.contains("a save landed"), "{said}");
105 assert!(said.contains("you asked"), "{said}");
106 assert!(said.contains("a warning"), "{said}");
107 }
108
109 #[test]
110 fn saying_everything_lets_the_routine_ones_through() {
111 let launcher = Launching::default();
112 let told = Told::default();
113 let outside = Outside::new(&Default_, &launcher, &told).saying(Notify::Everything);
114 for r in &three() {
115 outside.report(r);
116 }
117 assert_eq!(told.reports().len(), 3);
118 }
119
120 #[test]
121 fn no_setting_can_silence_a_question() {
122 let launcher = Launching::default();
127 let told = Told::default();
128 let outside = Outside::new(&Default_, &launcher, &told);
129 outside.channel.ask(&Question {
130 about: "abc-0".into(),
131 summary: "report.pdf was left behind.".into(),
132 detail: Vec::new(),
133 choices: vec![Choice::WriteBack, Choice::Discard],
134 });
135 assert_eq!(told.questions().len(), 1);
136 }
137}