1use std::io::Write;
2use std::marker::PhantomData;
3
4use crate::acore::opt::Opt;
5use crate::acore::Error;
6use crate::shell::Shell;
7use crate::SHELL_PSH;
8use crate::SHELL_PSH7;
9
10pub struct PowerShell<O, W> {
11 name: &'static str,
12 w: Option<W>,
13 __marker: PhantomData<O>,
14}
15
16impl<O, W> Default for PowerShell<O, W> {
17 fn default() -> Self {
18 Self {
19 name: SHELL_PSH,
20 w: Default::default(),
21 __marker: Default::default(),
22 }
23 }
24}
25
26impl<O, W> PowerShell<O, W> {
27 pub fn new() -> Self {
28 Self {
29 name: SHELL_PSH,
30 w: None,
31 __marker: PhantomData,
32 }
33 }
34
35 pub fn new7() -> Self {
36 Self {
37 name: SHELL_PSH7,
38 w: None,
39 __marker: PhantomData,
40 }
41 }
42
43 pub fn buffer(&mut self) -> Result<&mut W, Error> {
44 self.w
45 .as_mut()
46 .ok_or_else(|| crate::error!("must set buffer before write to"))
47 }
48
49 pub fn with_buffer(mut self, w: W) -> Self {
50 self.w = Some(w);
51 self
52 }
53}
54
55macro_rules! wln2buf {
56 ($w:expr, $fmt:literal, $($arg:tt)*) => {
57 writeln!( $w, $fmt, $($arg)* )
58 .map_err(|e| $crate::error!("can not write to buffer: {e:?}"))
59 };
60}
61
62impl<O, W> Shell<O, W> for PowerShell<O, W>
63where
64 W: Write,
65 O: Opt,
66{
67 type Err = Error;
68
69 fn is_avail(&self, name: &str) -> bool {
70 name == self.name
71 }
72
73 fn set_buff(&mut self, w: W) {
74 self.w = Some(w);
75 }
76
77 fn write_cmd(&mut self, name: &str, opt: &O) -> Result<(), Self::Err> {
78 if opt.help().is_empty() {
79 wln2buf!(self.buffer()?, "{}", name)
80 } else {
81 wln2buf!(self.buffer()?, "{}\t{}", name, opt.help())
82 }
83 }
84
85 fn write_opt(&mut self, name: &str, opt: &O) -> Result<(), Self::Err> {
86 if opt.help().is_empty() {
87 wln2buf!(self.buffer()?, "{}", name)
88 } else {
89 wln2buf!(self.buffer()?, "{}\t{}", name, opt.help())
90 }
91 }
92
93 fn write_pos(&mut self, name: &str, opt: &O) -> Result<(), Self::Err> {
94 if opt.help().is_empty() {
95 wln2buf!(self.buffer()?, "{}", name)
96 } else {
97 wln2buf!(self.buffer()?, "{}\t{}", name, opt.help())
98 }
99 }
100
101 fn write_val(&mut self, val: &std::ffi::OsStr, _: &O) -> Result<(), Self::Err> {
102 wln2buf!(self.buffer()?, "{}", val.display())
103 }
104
105 fn write_eq(&mut self, name: &str, val: &std::ffi::OsStr, _: &O) -> Result<(), Self::Err> {
106 wln2buf!(self.buffer()?, "{}={}", name, val.display())
107 }
108
109 fn finish(&mut self) -> Result<(), Self::Err> {
110 Ok(())
111 }
112
113 fn take_buff(&mut self) -> Option<W> {
114 self.w.take()
115 }
116}