1use embedded_io::Write;
2
3use crate::{arguments::FromArgumentError, cli::CliHandle, command::RawCommand};
4
5#[cfg(feature = "autocomplete")]
6use crate::autocomplete::{Autocompletion, Request};
7
8#[cfg(feature = "help")]
9use crate::writer::Writer;
10
11#[derive(Debug)]
12pub enum ProcessError<'a, E: embedded_io::Error> {
13 ParseError(ParseError<'a>),
14 WriteError(E),
15}
16
17#[derive(Debug)]
18#[non_exhaustive]
19pub enum ParseError<'a> {
20 MissingRequiredArgument {
21 name: &'a str,
23 },
24
25 NonAsciiShortOption,
26
27 ParseValueError {
28 value: &'a str,
29 expected: &'static str,
30 },
31
32 UnexpectedArgument {
33 value: &'a str,
34 },
35
36 UnexpectedLongOption {
37 name: &'a str,
38 },
39
40 UnexpectedShortOption {
41 name: char,
42 },
43
44 UnknownCommand,
45}
46
47impl<'a> From<FromArgumentError<'a>> for ParseError<'a> {
48 fn from(error: FromArgumentError<'a>) -> Self {
49 Self::ParseValueError {
50 value: error.value,
51 expected: error.expected,
52 }
53 }
54}
55
56impl<'a, E: embedded_io::Error> From<E> for ProcessError<'a, E> {
57 fn from(value: E) -> Self {
58 Self::WriteError(value)
59 }
60}
61
62impl<'a, E: embedded_io::Error> From<ParseError<'a>> for ProcessError<'a, E> {
63 fn from(value: ParseError<'a>) -> Self {
64 Self::ParseError(value)
65 }
66}
67
68#[derive(Debug)]
69pub enum HelpError<E: embedded_io::Error> {
70 WriteError(E),
71 UnknownCommand,
72}
73
74impl<E: embedded_io::Error> From<E> for HelpError<E> {
75 fn from(value: E) -> Self {
76 Self::WriteError(value)
77 }
78}
79
80pub trait Autocomplete {
81 #[cfg(feature = "autocomplete")]
83 fn autocomplete(request: Request<'_>, autocompletion: &mut Autocompletion<'_>);
87}
88
89pub trait Help {
91 #[cfg(feature = "help")]
92 fn command_count() -> usize;
94
95 #[cfg(feature = "help")]
96 fn list_commands<W: Write<Error = E>, E: embedded_io::Error>(
98 writer: &mut Writer<'_, W, E>,
99 ) -> Result<(), E>;
100
101 #[cfg(feature = "help")]
102 fn command_help<
107 W: Write<Error = E>,
108 E: embedded_io::Error,
109 F: FnMut(&mut Writer<'_, W, E>) -> Result<(), E>,
110 >(
111 parent: &mut F,
112 command: RawCommand<'_>,
113 writer: &mut Writer<'_, W, E>,
114 ) -> Result<(), HelpError<E>>;
115}
116
117pub trait FromRaw<'a>: Sized {
118 fn parse(raw: RawCommand<'a>) -> Result<Self, ParseError<'a>>;
120}
121
122pub trait CommandProcessor<W: Write<Error = E>, E: embedded_io::Error> {
123 fn process<'a>(
124 &mut self,
125 cli: &mut CliHandle<'_, W, E>,
126 raw: RawCommand<'a>,
127 ) -> Result<(), ProcessError<'a, E>>;
128}
129
130impl<W, E, F> CommandProcessor<W, E> for F
131where
132 W: Write<Error = E>,
133 E: embedded_io::Error,
134 F: for<'a> FnMut(&mut CliHandle<'_, W, E>, RawCommand<'a>) -> Result<(), ProcessError<'a, E>>,
135{
136 fn process<'a>(
137 &mut self,
138 cli: &mut CliHandle<'_, W, E>,
139 command: RawCommand<'a>,
140 ) -> Result<(), ProcessError<'a, E>> {
141 self(cli, command)
142 }
143}