pub struct AtParser<'a, T, const SIZE: usize>{
pub commands: &'a mut [(&'static str, &'static str, &'a mut T)],
}Expand description
The main AT command parser
Generic over T which must implement the AtContext<SIZE> trait,
and over the const SIZE which determines the response buffer size.
§Generic Design
The parser is generic over the command handler type T and response size SIZE to allow
compile-time type checking when all handlers are of the same type. This provides:
- Type safety: Compile-time verification of handler types
- Zero overhead: No dynamic dispatch when using concrete types
- Flexibility: Can be used with trait objects (
dyn AtContext<SIZE>) for mixed handler types
§Usage Patterns
§With trait objects (recommended for mixed types):
const SIZE: usize = 64;
let mut parser: AtParser<dyn AtContext<SIZE>, SIZE> = AtParser::new();
let commands: &mut [(&str, &mut dyn AtContext<SIZE>)] = &mut [
("AT+ECHO", &mut echo_handler),
("AT+RST", &mut reset_handler),
];
parser.set_commands(commands);§With concrete types (for homogeneous handlers):
const SIZE: usize = 64;
let mut parser: AtParser<MyHandler, SIZE> = AtParser::new();
let commands: &mut [(&str, &mut MyHandler)] = &mut [
("AT+CMD1", &mut handler1),
("AT+CMD2", &mut handler2),
];
parser.set_commands(commands);Fields§
§commands: &'a mut [(&'static str, &'static str, &'a mut T)]Array of registered commands with their command, AT response prefix, and handler
Implementations§
Source§impl<'a, T, const SIZE: usize> AtParser<'a, T, SIZE>
impl<'a, T, const SIZE: usize> AtParser<'a, T, SIZE>
Sourcepub const fn new() -> Self
pub const fn new() -> Self
Create a new empty parser with no registered commands.
Call set_commands before dispatching any
input with execute.
§Example
let mut parser: AtParser<MyHandler, SIZE> = AtParser::new();
// parser has no commands yet; execute() will return Err(UnknownCommand)Examples found in repository?
83pub extern "C" fn main() -> ! {
84 let mut diag = DiagModule { armed: false };
85
86 let mut parser: AtParser<DiagModule, SIZE> = AtParser::new();
87 let commands: &mut [(&str, &str, &mut DiagModule)] = &mut [
88 ("AT+DIAG", "+DIAG: ", &mut diag),
89 ];
90 parser.set_commands(commands);
91
92 // Not armed yet: exec returns Unhandled
93 let _s = check_result(parser.execute("AT+DIAG")); // -> 4
94
95 // Arm it
96 let _s = check_result(parser.execute("AT+DIAG=1")); // -> 0
97
98 // Now exec succeeds
99 let _s = check_result(parser.execute("AT+DIAG")); // -> 0
100
101 // Query state
102 let _s = check_result(parser.execute("AT+DIAG?")); // -> 0
103
104 // Invalid argument
105 let _s = check_result(parser.execute("AT+DIAG=2")); // -> 1
106
107 // Unknown command
108 let _s = check_result(parser.execute("AT+UNKNOWN")); // -> 3
109
110 loop {}
111}More examples
121pub extern "C" fn main() -> ! {
122 let mut uart = UartSendModule::new();
123 let mut config = ConfigModule::new();
124
125 let mut parser: AtParser<dyn AtContext<SIZE>, SIZE> = AtParser::new();
126 let commands: &mut [(&str, &str, &mut dyn AtContext<SIZE>)] = &mut [
127 ("AT+UARTSEND", "+UARTSEND: ", &mut uart),
128 ("AT+CFG", "+CFG: ", &mut config),
129 ];
130 parser.set_commands(commands);
131
132 // Test: show syntax
133 let _ = parser.execute("AT+UARTSEND=?"); // Ok(("+UARTSEND: ", "\"<data>\""))
134 let _ = parser.execute("AT+CFG=?"); // Ok(("+CFG: ", "<baudrate: 9600-115200>,<mode: 0|1>"))
135
136 // Query current config
137 let _ = parser.execute("AT+CFG?"); // Ok(("+CFG: ", "115200,0"))
138
139 // Send data over UART
140 let _ = parser.execute("AT+UARTSEND=\"hello\""); // Ok(("+UARTSEND: ", "SENT"))
141
142 // Set new configuration
143 let _ = parser.execute("AT+CFG=9600,1"); // Ok(("+CFG: ", "OK"))
144 let _ = parser.execute("AT+CFG?"); // Ok(("+CFG: ", "9600,1"))
145
146 // Error cases
147 let _ = parser.execute("AT+CFG=9600,5"); // Err(("+CFG: ", InvalidArgs)) — mode > 1
148 let _ = parser.execute("AT+CFG=abc,0"); // Err(("+CFG: ", InvalidArgs)) — bad baudrate
149
150 loop {}
151}64pub extern "C" fn main() -> ! {
65 let mut cmd1 = TestCommand { value: 0 };
66 let mut cmd2 = TestCommand { value: 5 };
67 let mut cmd3 = TestCommand { value: 10 };
68
69 let mut parser: AtParser<TestCommand, SIZE> = AtParser::new();
70
71 let commands: &mut [(&str, &str, &mut TestCommand)] = &mut [
72 ("AT+CMD1", "+CMD1: ", &mut cmd1),
73 ("AT+CMD2", "+CMD2: ", &mut cmd2),
74 ("AT+CMD3", "+CMD3: ", &mut cmd3),
75 ];
76 parser.set_commands(commands);
77
78 let _ = parser.execute("AT+CMD1"); // Ok(("+CMD1: ", "executed"))
79 let _ = parser.execute("AT+CMD1?"); // Ok(("+CMD1: ", "0"))
80 let _ = parser.execute("AT+CMD1=?"); // Ok(("+CMD1: ", "(0-100)"))
81 let _ = parser.execute("AT+CMD1=42"); // Ok(("+CMD1: ", "OK"))
82 let _ = parser.execute("AT+CMD1?"); // Ok(("+CMD1: ", "42"))
83 let _ = parser.execute("AT+CMD2"); // Ok(("+CMD2: ", "executed"))
84 let _ = parser.execute("AT+CMD2?"); // Ok(("+CMD2: ", "5"))
85 let _ = parser.execute("AT+CMD3=100"); // Ok(("+CMD3: ", "OK"))
86 let _ = parser.execute("AT+CMD3?"); // Ok(("+CMD3: ", "100"))
87 let _ = parser.execute("AT+UNKNOWN"); // Err(("", UnknownCommand))
88 let _ = parser.execute("AT+CMD1=abc"); // Err(("+CMD1: ", InvalidArgs))
89
90 loop {}
91}157pub extern "C" fn main() -> ! {
158 let mut echo = EchoModule { echo: false };
159 let mut reset = ResetModule;
160 let mut info = InfoModule { version: "v1.0.0" };
161 let mut led = LedModule { state: false, brightness: 0 };
162
163 let mut parser: AtParser<dyn AtContext<SIZE>, SIZE> = AtParser::new();
164
165 let commands: &mut [(&str, &str, &mut dyn AtContext<SIZE>)] = &mut [
166 ("AT+ECHO", "+ECHO: ", &mut echo),
167 ("AT+RST", "+RST: ", &mut reset),
168 ("AT+INFO", "+INFO: ", &mut info),
169 ("AT+LED", "+LED: ", &mut led),
170 ];
171 parser.set_commands(commands);
172
173 // INFO
174 let _ = parser.execute("AT+INFO"); // Ok(("+INFO: ", "v1.0.0"))
175 let _ = parser.execute("AT+INFO?"); // Ok(("+INFO: ", "AT-Parser-RS ..."))
176
177 // ECHO
178 let _ = parser.execute("AT+ECHO"); // Ok(("+ECHO: ", "OFF"))
179 let _ = parser.execute("AT+ECHO=?"); // Ok(("+ECHO: ", "(0,1)"))
180 let _ = parser.execute("AT+ECHO=1"); // Ok(("+ECHO: ", "OK"))
181 let _ = parser.execute("AT+ECHO?"); // Ok(("+ECHO: ", "1"))
182 let _ = parser.execute("AT+ECHO=0"); // Ok(("+ECHO: ", "OK"))
183
184 // LED
185 let _ = parser.execute("AT+LED=?"); // Ok(("+LED: ", "<state: 0|1>,<brightness: 0-100>"))
186 let _ = parser.execute("AT+LED=1"); // Ok(("+LED: ", "OK"))
187 let _ = parser.execute("AT+LED?"); // Ok(("+LED: ", "1,0"))
188 let _ = parser.execute("AT+LED=1,75"); // Ok(("+LED: ", "OK"))
189 let _ = parser.execute("AT+LED=0"); // Ok(("+LED: ", "OK"))
190
191 // RESET
192 let _ = parser.execute("AT+RST=?"); // Ok(("+RST: ", "Reset the system"))
193 let _ = parser.execute("AT+RST"); // Ok(("+RST: ", "OK"))
194
195 // Error cases
196 let _ = parser.execute("AT+ECHO=2"); // Err(("+ECHO: ", InvalidArgs))
197 let _ = parser.execute("AT+UNKNOWN"); // Err(("", UnknownCommand))
198
199 loop {}
200}Sourcepub fn set_commands(
&mut self,
commands: &'a mut [(&'static str, &'static str, &'a mut T)],
)
pub fn set_commands( &mut self, commands: &'a mut [(&'static str, &'static str, &'a mut T)], )
Register the commands that this parser will dispatch.
The slice maps each AT command to a mutable reference to its handler via
3-tuples: (at_command, at_response, handler).
at_command— the string matched verbatim against the input prefix (e.g."AT+ECHO")at_response— prefix forwarded to every handler method (e.g."+ECHO: ")handler— mutable reference to theAtContextimplementation
Matching is case-sensitive.
§Arguments
commands— mutable slice of(&'static str, &'static str, &mut T)triples
§Example
struct PingModule;
impl AtContext<SIZE> for PingModule {
fn exec(&mut self, at_response: &'static str) -> AtResult<'_, SIZE> {
Ok(at_response!(SIZE, at_response; "PONG"))
}
}
let mut ping = PingModule;
let mut parser: AtParser<PingModule, SIZE> = AtParser::new();
let commands: &mut [(&str, &str, &mut PingModule)] = &mut [
("AT+PING", "+PING: ", &mut ping),
];
parser.set_commands(commands);Using trait objects to mix different handler types:
let mut ping = PingModule;
let mut echo = EchoModule;
let mut parser: AtParser<dyn AtContext<SIZE>, SIZE> = AtParser::new();
let commands: &mut [(&str, &str, &mut dyn AtContext<SIZE>)] = &mut [
("AT+PING", "+PING: ", &mut ping),
("AT+ECHO", "+ECHO: ", &mut echo),
];
parser.set_commands(commands);Examples found in repository?
83pub extern "C" fn main() -> ! {
84 let mut diag = DiagModule { armed: false };
85
86 let mut parser: AtParser<DiagModule, SIZE> = AtParser::new();
87 let commands: &mut [(&str, &str, &mut DiagModule)] = &mut [
88 ("AT+DIAG", "+DIAG: ", &mut diag),
89 ];
90 parser.set_commands(commands);
91
92 // Not armed yet: exec returns Unhandled
93 let _s = check_result(parser.execute("AT+DIAG")); // -> 4
94
95 // Arm it
96 let _s = check_result(parser.execute("AT+DIAG=1")); // -> 0
97
98 // Now exec succeeds
99 let _s = check_result(parser.execute("AT+DIAG")); // -> 0
100
101 // Query state
102 let _s = check_result(parser.execute("AT+DIAG?")); // -> 0
103
104 // Invalid argument
105 let _s = check_result(parser.execute("AT+DIAG=2")); // -> 1
106
107 // Unknown command
108 let _s = check_result(parser.execute("AT+UNKNOWN")); // -> 3
109
110 loop {}
111}More examples
121pub extern "C" fn main() -> ! {
122 let mut uart = UartSendModule::new();
123 let mut config = ConfigModule::new();
124
125 let mut parser: AtParser<dyn AtContext<SIZE>, SIZE> = AtParser::new();
126 let commands: &mut [(&str, &str, &mut dyn AtContext<SIZE>)] = &mut [
127 ("AT+UARTSEND", "+UARTSEND: ", &mut uart),
128 ("AT+CFG", "+CFG: ", &mut config),
129 ];
130 parser.set_commands(commands);
131
132 // Test: show syntax
133 let _ = parser.execute("AT+UARTSEND=?"); // Ok(("+UARTSEND: ", "\"<data>\""))
134 let _ = parser.execute("AT+CFG=?"); // Ok(("+CFG: ", "<baudrate: 9600-115200>,<mode: 0|1>"))
135
136 // Query current config
137 let _ = parser.execute("AT+CFG?"); // Ok(("+CFG: ", "115200,0"))
138
139 // Send data over UART
140 let _ = parser.execute("AT+UARTSEND=\"hello\""); // Ok(("+UARTSEND: ", "SENT"))
141
142 // Set new configuration
143 let _ = parser.execute("AT+CFG=9600,1"); // Ok(("+CFG: ", "OK"))
144 let _ = parser.execute("AT+CFG?"); // Ok(("+CFG: ", "9600,1"))
145
146 // Error cases
147 let _ = parser.execute("AT+CFG=9600,5"); // Err(("+CFG: ", InvalidArgs)) — mode > 1
148 let _ = parser.execute("AT+CFG=abc,0"); // Err(("+CFG: ", InvalidArgs)) — bad baudrate
149
150 loop {}
151}64pub extern "C" fn main() -> ! {
65 let mut cmd1 = TestCommand { value: 0 };
66 let mut cmd2 = TestCommand { value: 5 };
67 let mut cmd3 = TestCommand { value: 10 };
68
69 let mut parser: AtParser<TestCommand, SIZE> = AtParser::new();
70
71 let commands: &mut [(&str, &str, &mut TestCommand)] = &mut [
72 ("AT+CMD1", "+CMD1: ", &mut cmd1),
73 ("AT+CMD2", "+CMD2: ", &mut cmd2),
74 ("AT+CMD3", "+CMD3: ", &mut cmd3),
75 ];
76 parser.set_commands(commands);
77
78 let _ = parser.execute("AT+CMD1"); // Ok(("+CMD1: ", "executed"))
79 let _ = parser.execute("AT+CMD1?"); // Ok(("+CMD1: ", "0"))
80 let _ = parser.execute("AT+CMD1=?"); // Ok(("+CMD1: ", "(0-100)"))
81 let _ = parser.execute("AT+CMD1=42"); // Ok(("+CMD1: ", "OK"))
82 let _ = parser.execute("AT+CMD1?"); // Ok(("+CMD1: ", "42"))
83 let _ = parser.execute("AT+CMD2"); // Ok(("+CMD2: ", "executed"))
84 let _ = parser.execute("AT+CMD2?"); // Ok(("+CMD2: ", "5"))
85 let _ = parser.execute("AT+CMD3=100"); // Ok(("+CMD3: ", "OK"))
86 let _ = parser.execute("AT+CMD3?"); // Ok(("+CMD3: ", "100"))
87 let _ = parser.execute("AT+UNKNOWN"); // Err(("", UnknownCommand))
88 let _ = parser.execute("AT+CMD1=abc"); // Err(("+CMD1: ", InvalidArgs))
89
90 loop {}
91}157pub extern "C" fn main() -> ! {
158 let mut echo = EchoModule { echo: false };
159 let mut reset = ResetModule;
160 let mut info = InfoModule { version: "v1.0.0" };
161 let mut led = LedModule { state: false, brightness: 0 };
162
163 let mut parser: AtParser<dyn AtContext<SIZE>, SIZE> = AtParser::new();
164
165 let commands: &mut [(&str, &str, &mut dyn AtContext<SIZE>)] = &mut [
166 ("AT+ECHO", "+ECHO: ", &mut echo),
167 ("AT+RST", "+RST: ", &mut reset),
168 ("AT+INFO", "+INFO: ", &mut info),
169 ("AT+LED", "+LED: ", &mut led),
170 ];
171 parser.set_commands(commands);
172
173 // INFO
174 let _ = parser.execute("AT+INFO"); // Ok(("+INFO: ", "v1.0.0"))
175 let _ = parser.execute("AT+INFO?"); // Ok(("+INFO: ", "AT-Parser-RS ..."))
176
177 // ECHO
178 let _ = parser.execute("AT+ECHO"); // Ok(("+ECHO: ", "OFF"))
179 let _ = parser.execute("AT+ECHO=?"); // Ok(("+ECHO: ", "(0,1)"))
180 let _ = parser.execute("AT+ECHO=1"); // Ok(("+ECHO: ", "OK"))
181 let _ = parser.execute("AT+ECHO?"); // Ok(("+ECHO: ", "1"))
182 let _ = parser.execute("AT+ECHO=0"); // Ok(("+ECHO: ", "OK"))
183
184 // LED
185 let _ = parser.execute("AT+LED=?"); // Ok(("+LED: ", "<state: 0|1>,<brightness: 0-100>"))
186 let _ = parser.execute("AT+LED=1"); // Ok(("+LED: ", "OK"))
187 let _ = parser.execute("AT+LED?"); // Ok(("+LED: ", "1,0"))
188 let _ = parser.execute("AT+LED=1,75"); // Ok(("+LED: ", "OK"))
189 let _ = parser.execute("AT+LED=0"); // Ok(("+LED: ", "OK"))
190
191 // RESET
192 let _ = parser.execute("AT+RST=?"); // Ok(("+RST: ", "Reset the system"))
193 let _ = parser.execute("AT+RST"); // Ok(("+RST: ", "OK"))
194
195 // Error cases
196 let _ = parser.execute("AT+ECHO=2"); // Err(("+ECHO: ", InvalidArgs))
197 let _ = parser.execute("AT+UNKNOWN"); // Err(("", UnknownCommand))
198
199 loop {}
200}Sourcepub fn execute<'b>(&'b mut self, input: &'b str) -> AtResult<'b, SIZE>
pub fn execute<'b>(&'b mut self, input: &'b str) -> AtResult<'b, SIZE>
Parse and execute an AT command string.
Leading and trailing whitespace is stripped before parsing. The command name is matched against the registered commands; if found, the appropriate handler method is called based on the command form detected from the suffix.
§Arguments
input— raw AT command string (e.g."AT+CMD?","AT+CMD=1,2")
§Returns
Ok(Bytes<SIZE>)— response buffer returned by the matched handlerErr(AtError::UnknownCommand)— no handler found for the command nameErr(AtError::NotSupported)— handler found but the requested form is not implementedErr(AtError::InvalidArgs)— handler returned an argument error
§Example
struct EchoModule { enabled: bool }
impl AtContext<SIZE> for EchoModule {
fn query(&mut self, at_response: &'static str) -> AtResult<'_, SIZE> {
Ok(at_response!(SIZE, at_response; if self.enabled { 1u8 } else { 0u8 }))
}
fn set(&mut self, at_response: &'static str, args: Args) -> AtResult<'_, SIZE> {
let value = args.get(0).ok_or((at_response, AtError::InvalidArgs))?;
match value.as_ref() {
"0" => { self.enabled = false; Ok(at_response!(SIZE, at_response; "OK")) }
"1" => { self.enabled = true; Ok(at_response!(SIZE, at_response; "OK")) }
_ => Err((at_response, AtError::InvalidArgs)),
}
}
}
let mut echo = EchoModule { enabled: false };
let mut parser: AtParser<EchoModule, SIZE> = AtParser::new();
let commands: &mut [(&str, &str, &mut EchoModule)] = &mut [
("AT+ECHO", "+ECHO: ", &mut echo)
];
parser.set_commands(commands);
assert!(parser.execute("AT+ECHO=1").is_ok()); // Ok(("+ECHO: ", "OK"))
assert!(parser.execute("AT+ECHO?").is_ok()); // Ok(("+ECHO: ", "1"))
assert!(parser.execute("AT+UNKNOWN").is_err()); // Err(("", UnknownCommand))
assert!(parser.execute("AT+ECHO=9").is_err()); // Err(("+ECHO: ", InvalidArgs))Examples found in repository?
83pub extern "C" fn main() -> ! {
84 let mut diag = DiagModule { armed: false };
85
86 let mut parser: AtParser<DiagModule, SIZE> = AtParser::new();
87 let commands: &mut [(&str, &str, &mut DiagModule)] = &mut [
88 ("AT+DIAG", "+DIAG: ", &mut diag),
89 ];
90 parser.set_commands(commands);
91
92 // Not armed yet: exec returns Unhandled
93 let _s = check_result(parser.execute("AT+DIAG")); // -> 4
94
95 // Arm it
96 let _s = check_result(parser.execute("AT+DIAG=1")); // -> 0
97
98 // Now exec succeeds
99 let _s = check_result(parser.execute("AT+DIAG")); // -> 0
100
101 // Query state
102 let _s = check_result(parser.execute("AT+DIAG?")); // -> 0
103
104 // Invalid argument
105 let _s = check_result(parser.execute("AT+DIAG=2")); // -> 1
106
107 // Unknown command
108 let _s = check_result(parser.execute("AT+UNKNOWN")); // -> 3
109
110 loop {}
111}More examples
121pub extern "C" fn main() -> ! {
122 let mut uart = UartSendModule::new();
123 let mut config = ConfigModule::new();
124
125 let mut parser: AtParser<dyn AtContext<SIZE>, SIZE> = AtParser::new();
126 let commands: &mut [(&str, &str, &mut dyn AtContext<SIZE>)] = &mut [
127 ("AT+UARTSEND", "+UARTSEND: ", &mut uart),
128 ("AT+CFG", "+CFG: ", &mut config),
129 ];
130 parser.set_commands(commands);
131
132 // Test: show syntax
133 let _ = parser.execute("AT+UARTSEND=?"); // Ok(("+UARTSEND: ", "\"<data>\""))
134 let _ = parser.execute("AT+CFG=?"); // Ok(("+CFG: ", "<baudrate: 9600-115200>,<mode: 0|1>"))
135
136 // Query current config
137 let _ = parser.execute("AT+CFG?"); // Ok(("+CFG: ", "115200,0"))
138
139 // Send data over UART
140 let _ = parser.execute("AT+UARTSEND=\"hello\""); // Ok(("+UARTSEND: ", "SENT"))
141
142 // Set new configuration
143 let _ = parser.execute("AT+CFG=9600,1"); // Ok(("+CFG: ", "OK"))
144 let _ = parser.execute("AT+CFG?"); // Ok(("+CFG: ", "9600,1"))
145
146 // Error cases
147 let _ = parser.execute("AT+CFG=9600,5"); // Err(("+CFG: ", InvalidArgs)) — mode > 1
148 let _ = parser.execute("AT+CFG=abc,0"); // Err(("+CFG: ", InvalidArgs)) — bad baudrate
149
150 loop {}
151}64pub extern "C" fn main() -> ! {
65 let mut cmd1 = TestCommand { value: 0 };
66 let mut cmd2 = TestCommand { value: 5 };
67 let mut cmd3 = TestCommand { value: 10 };
68
69 let mut parser: AtParser<TestCommand, SIZE> = AtParser::new();
70
71 let commands: &mut [(&str, &str, &mut TestCommand)] = &mut [
72 ("AT+CMD1", "+CMD1: ", &mut cmd1),
73 ("AT+CMD2", "+CMD2: ", &mut cmd2),
74 ("AT+CMD3", "+CMD3: ", &mut cmd3),
75 ];
76 parser.set_commands(commands);
77
78 let _ = parser.execute("AT+CMD1"); // Ok(("+CMD1: ", "executed"))
79 let _ = parser.execute("AT+CMD1?"); // Ok(("+CMD1: ", "0"))
80 let _ = parser.execute("AT+CMD1=?"); // Ok(("+CMD1: ", "(0-100)"))
81 let _ = parser.execute("AT+CMD1=42"); // Ok(("+CMD1: ", "OK"))
82 let _ = parser.execute("AT+CMD1?"); // Ok(("+CMD1: ", "42"))
83 let _ = parser.execute("AT+CMD2"); // Ok(("+CMD2: ", "executed"))
84 let _ = parser.execute("AT+CMD2?"); // Ok(("+CMD2: ", "5"))
85 let _ = parser.execute("AT+CMD3=100"); // Ok(("+CMD3: ", "OK"))
86 let _ = parser.execute("AT+CMD3?"); // Ok(("+CMD3: ", "100"))
87 let _ = parser.execute("AT+UNKNOWN"); // Err(("", UnknownCommand))
88 let _ = parser.execute("AT+CMD1=abc"); // Err(("+CMD1: ", InvalidArgs))
89
90 loop {}
91}157pub extern "C" fn main() -> ! {
158 let mut echo = EchoModule { echo: false };
159 let mut reset = ResetModule;
160 let mut info = InfoModule { version: "v1.0.0" };
161 let mut led = LedModule { state: false, brightness: 0 };
162
163 let mut parser: AtParser<dyn AtContext<SIZE>, SIZE> = AtParser::new();
164
165 let commands: &mut [(&str, &str, &mut dyn AtContext<SIZE>)] = &mut [
166 ("AT+ECHO", "+ECHO: ", &mut echo),
167 ("AT+RST", "+RST: ", &mut reset),
168 ("AT+INFO", "+INFO: ", &mut info),
169 ("AT+LED", "+LED: ", &mut led),
170 ];
171 parser.set_commands(commands);
172
173 // INFO
174 let _ = parser.execute("AT+INFO"); // Ok(("+INFO: ", "v1.0.0"))
175 let _ = parser.execute("AT+INFO?"); // Ok(("+INFO: ", "AT-Parser-RS ..."))
176
177 // ECHO
178 let _ = parser.execute("AT+ECHO"); // Ok(("+ECHO: ", "OFF"))
179 let _ = parser.execute("AT+ECHO=?"); // Ok(("+ECHO: ", "(0,1)"))
180 let _ = parser.execute("AT+ECHO=1"); // Ok(("+ECHO: ", "OK"))
181 let _ = parser.execute("AT+ECHO?"); // Ok(("+ECHO: ", "1"))
182 let _ = parser.execute("AT+ECHO=0"); // Ok(("+ECHO: ", "OK"))
183
184 // LED
185 let _ = parser.execute("AT+LED=?"); // Ok(("+LED: ", "<state: 0|1>,<brightness: 0-100>"))
186 let _ = parser.execute("AT+LED=1"); // Ok(("+LED: ", "OK"))
187 let _ = parser.execute("AT+LED?"); // Ok(("+LED: ", "1,0"))
188 let _ = parser.execute("AT+LED=1,75"); // Ok(("+LED: ", "OK"))
189 let _ = parser.execute("AT+LED=0"); // Ok(("+LED: ", "OK"))
190
191 // RESET
192 let _ = parser.execute("AT+RST=?"); // Ok(("+RST: ", "Reset the system"))
193 let _ = parser.execute("AT+RST"); // Ok(("+RST: ", "OK"))
194
195 // Error cases
196 let _ = parser.execute("AT+ECHO=2"); // Err(("+ECHO: ", InvalidArgs))
197 let _ = parser.execute("AT+UNKNOWN"); // Err(("", UnknownCommand))
198
199 loop {}
200}