complete_usage/
complete_usage.rs

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