complete_usage/
complete_usage.rs

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