aopt_shell/shell/
fish.rs

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