1use super::{Context, Input, Result};
20use crate::Env;
21use crate::option::Option::Verbose;
22use crate::option::State::On;
23use std::cell::RefCell;
24
25#[derive(Clone, Debug)]
32#[doc(alias = "Verbose")]
33#[must_use = "Echo does nothing unless used by a parser"]
34pub struct Echo<'a, 'b, T> {
35 inner: T,
36 env: &'a RefCell<&'b mut Env>,
37}
38
39impl<'a, 'b, T> Echo<'a, 'b, T> {
40 pub fn new(inner: T, env: &'a RefCell<&'b mut Env>) -> Self {
48 Self { inner, env }
49 }
50}
51
52impl<T> Input for Echo<'_, '_, T>
53where
54 T: Input,
55{
56 #[allow(clippy::await_holding_refcell_ref)]
59 async fn next_line(&mut self, context: &Context) -> Result {
60 let line = self.inner.next_line(context).await?;
61
62 let env = &mut **self.env.borrow_mut();
63 if env.options.get(Verbose) == On {
64 env.system.print_error(&line).await;
65 }
66
67 Ok(line)
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::super::Memory;
74 use super::*;
75 use crate::system::r#virtual::VirtualSystem;
76 use crate::tests::assert_stderr;
77 use futures_util::FutureExt;
78 use std::rc::Rc;
79
80 #[test]
81 fn verbose_off() {
82 let system = Box::new(VirtualSystem::new());
83 let state = Rc::clone(&system.state);
84 let mut env = Env::with_system(system);
85 let ref_env = RefCell::new(&mut env);
86 let memory = Memory::new("echo test\n");
87 let mut echo = Echo::new(memory, &ref_env);
88
89 let line = echo
90 .next_line(&Context::default())
91 .now_or_never()
92 .unwrap()
93 .unwrap();
94 assert_eq!(line, "echo test\n");
95 assert_stderr(&state, |stderr| assert_eq!(stderr, ""));
96 }
97
98 #[test]
99 fn verbose_on() {
100 let system = Box::new(VirtualSystem::new());
101 let state = Rc::clone(&system.state);
102 let mut env = Env::with_system(system);
103 env.options.set(Verbose, On);
104 let ref_env = RefCell::new(&mut env);
105 let memory = Memory::new("echo test\nfoo");
106 let mut echo = Echo::new(memory, &ref_env);
107
108 let line = echo
109 .next_line(&Context::default())
110 .now_or_never()
111 .unwrap()
112 .unwrap();
113 assert_eq!(line, "echo test\n");
114 assert_stderr(&state, |stderr| assert_eq!(stderr, "echo test\n"));
115
116 let line = echo
117 .next_line(&Context::default())
118 .now_or_never()
119 .unwrap()
120 .unwrap();
121 assert_eq!(line, "foo");
122 assert_stderr(&state, |stderr| assert_eq!(stderr, "echo test\nfoo"));
123 }
124}