Skip to main content

complete_usage/
complete_usage.rs

1/***************************************************************************
2 *
3 * AT Command Parser
4 * Copyright (C) 2026 Antonio Salsi <passy.linux@zresa.it>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <https://www.gnu.org/licenses/>.
18 *
19 ***************************************************************************/
20 
21//! Complete example demonstrating the AT command parser functionality
22
23use at_parser_rs::context::AtContext;
24use at_parser_rs::{Args, AtError, AtResult};
25
26/// Echo command module - manages echo state
27pub struct EchoModule {
28    pub echo: bool,
29}
30
31impl AtContext for EchoModule {
32    /// Execute: return current echo state
33    fn exec(&self) -> AtResult<'static> {
34        if self.echo {
35            Ok("ECHO: ON")
36        } else {
37            Ok("ECHO: OFF")
38        }
39    }
40
41    /// Query: return current echo value
42    fn query(&mut self) -> AtResult<'static> {
43        if self.echo {
44            Ok("1")
45        } else {
46            Ok("0")
47        }
48    }
49
50    /// Test: show valid values
51    fn test(&mut self) -> AtResult<'static> {
52        Ok("Valid values: 0 (OFF), 1 (ON)")
53    }
54
55    /// Set: enable/disable echo
56    fn set(&mut self, args: Args) -> AtResult<'static> {
57        let value = args.get(0).ok_or(AtError::InvalidArgs)?;
58        match value {
59            "0" => {
60                self.echo = false;
61                Ok("ECHO OFF")
62            }
63            "1" => {
64                self.echo = true;
65                Ok("ECHO ON")
66            }
67            _ => Err(AtError::InvalidArgs),
68        }
69    }
70}
71
72/// Reset command module - simulates system reset
73pub struct ResetModule;
74
75impl AtContext for ResetModule {
76    /// Execute: perform reset
77    fn exec(&self) -> AtResult<'static> {
78        println!("  [System reset triggered]");
79        Ok("OK - System reset")
80    }
81
82    /// Test: show command description
83    fn test(&mut self) -> AtResult<'static> {
84        Ok("Reset the system")
85    }
86}
87
88/// Info command module - provides system information
89pub struct InfoModule {
90    pub version: &'static str,
91}
92
93impl AtContext for InfoModule {
94    /// Execute: return system info
95    fn exec(&self) -> AtResult<'static> {
96        Ok(self.version)
97    }
98
99    /// Query: return detailed info
100    fn query(&mut self) -> AtResult<'static> {
101        Ok("AT-Parser-RS v1.0.0 - AT Command Parser Library")
102    }
103}
104
105/// LED command module - controls an LED with multiple parameters
106pub struct LedModule {
107    pub state: bool,
108    pub brightness: u8,
109}
110
111impl AtContext for LedModule {
112    /// Execute: return current LED state
113    fn exec(&self) -> AtResult<'static> {
114        if self.state {
115            Ok("LED: ON")
116        } else {
117            Ok("LED: OFF")
118        }
119    }
120
121    /// Query: return state and brightness
122    fn query(&mut self) -> AtResult<'static> {
123        if self.state {
124            Ok("1,100")
125        } else {
126            Ok("0,0")
127        }
128    }
129
130    /// Test: show usage
131    fn test(&mut self) -> AtResult<'static> {
132        Ok("AT+LED=<state>,<brightness> where state: 0|1, brightness: 0-100")
133    }
134
135    /// Set: change LED state and brightness
136    fn set(&mut self, args: Args) -> AtResult<'static> {
137        let state_str = args.get(0).ok_or(AtError::InvalidArgs)?;
138        
139        self.state = match state_str {
140            "0" => false,
141            "1" => true,
142            _ => return Err(AtError::InvalidArgs),
143        };
144
145        // Optional brightness parameter
146        if let Some(brightness_str) = args.get(1) {
147            self.brightness = brightness_str
148                .parse::<u8>()
149                .map_err(|_| AtError::InvalidArgs)?;
150            
151            if self.brightness > 100 {
152                return Err(AtError::InvalidArgs);
153            }
154        }
155
156        if self.state {
157            Ok("LED ON")
158        } else {
159            Ok("LED OFF")
160        }
161    }
162}
163
164/// Helper function to execute a command and print the result
165fn execute_command(cmd: &str, name: &str, module: &mut dyn AtContext) {
166    println!("\n> {}", cmd);
167    
168    let result = if let Some(rest) = cmd.strip_prefix(name) {
169        if rest.is_empty() {
170            // Execute form: AT+CMD
171            module.exec()
172        } else if rest == "?" {
173            // Query form: AT+CMD?
174            module.query()
175        } else if rest == "=?" {
176            // Test form: AT+CMD=?
177            module.test()
178        } else if let Some(args_str) = rest.strip_prefix('=') {
179            // Set form: AT+CMD=args
180            module.set(Args { raw: args_str })
181        } else {
182            Err(AtError::InvalidArgs)
183        }
184    } else {
185        Err(AtError::UnknownCommand)
186    };
187    
188    match result {
189        Ok(response) => println!("  Response: {}", response),
190        Err(AtError::UnknownCommand) => println!("  Error: Unknown command"),
191        Err(AtError::NotSupported) => println!("  Error: Operation not supported"),
192        Err(AtError::InvalidArgs) => println!("  Error: Invalid arguments"),
193    }
194}
195
196fn main() {
197    println!("=== AT Command Parser Example ===\n");
198    println!("Available commands: AT+ECHO, AT+RST, AT+INFO, AT+LED\n");
199
200    // Create module instances
201    let mut echo = EchoModule { echo: false };
202    let mut reset = ResetModule;
203    let mut info = InfoModule { version: "v1.0.0" };
204    let mut led = LedModule {
205        state: false,
206        brightness: 0,
207    };
208
209    // Demonstrate all command forms
210    
211    // 1. INFO command examples
212    println!("--- INFO Command ---");
213    execute_command("AT+INFO", "AT+INFO", &mut info);      // Execute
214    execute_command("AT+INFO?", "AT+INFO", &mut info);     // Query
215
216    // 2. ECHO command examples
217    println!("\n--- ECHO Command ---");
218    execute_command("AT+ECHO", "AT+ECHO", &mut echo);      // Execute (current state)
219    execute_command("AT+ECHO=?", "AT+ECHO", &mut echo);    // Test (show valid values)
220    execute_command("AT+ECHO=1", "AT+ECHO", &mut echo);    // Set (enable)
221    execute_command("AT+ECHO?", "AT+ECHO", &mut echo);     // Query (check state)
222    execute_command("AT+ECHO", "AT+ECHO", &mut echo);      // Execute (should show ON)
223    execute_command("AT+ECHO=0", "AT+ECHO", &mut echo);    // Set (disable)
224    execute_command("AT+ECHO", "AT+ECHO", &mut echo);      // Execute (should show OFF)
225
226    // 3. LED command examples
227    println!("\n--- LED Command ---");
228    execute_command("AT+LED=?", "AT+LED", &mut led);       // Test (show usage)
229    execute_command("AT+LED=1", "AT+LED", &mut led);       // Set (turn on)
230    execute_command("AT+LED?", "AT+LED", &mut led);        // Query
231    execute_command("AT+LED=1,75", "AT+LED", &mut led);    // Set with brightness
232    execute_command("AT+LED", "AT+LED", &mut led);         // Execute (current state)
233    execute_command("AT+LED=0", "AT+LED", &mut led);       // Set (turn off)
234
235    // 4. RESET command example
236    println!("\n--- RESET Command ---");
237    execute_command("AT+RST=?", "AT+RST", &mut reset);     // Test
238    execute_command("AT+RST", "AT+RST", &mut reset);       // Execute
239
240    // 5. Error handling examples
241    println!("\n--- Error Handling ---");
242    execute_command("AT+ECHO=2", "AT+ECHO", &mut echo);    // Invalid argument
243    execute_command("AT+INFO=1", "AT+INFO", &mut info);    // Set not supported for INFO
244
245    println!("\n=== Example completed ===");
246}