Skip to main content

basic_parser/
basic_parser.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//! Example using the AtParser with proper type handling
22//!
23//! **Note**: no_std compatible example - designed to compile and run on embedded
24//! targets. Demonstrates AtParser usage patterns without std dependency.
25
26#![no_std]
27#![no_main]
28#![allow(dead_code, unused_variables)]
29
30extern crate at_parser_rs;
31
32use at_parser_rs::context::AtContext;
33use at_parser_rs::parser::AtParser;
34use at_parser_rs::{Args, AtError, AtResult, at_response};
35
36const SIZE: usize = 64;
37
38/// Simple command module for testing
39pub struct TestCommand {
40    pub value: u32,
41}
42
43impl AtContext<SIZE> for TestCommand {
44    fn exec(&mut self, at_response: &'static str) -> AtResult<'_, SIZE> {
45        Ok(at_response!(SIZE, at_response; "executed"))
46    }
47
48    fn query(&mut self, at_response: &'static str) -> AtResult<'_, SIZE> {
49        Ok(at_response!(SIZE, at_response; self.value))
50    }
51
52    fn test(&mut self, at_response: &'static str) -> AtResult<'_, SIZE> {
53        Ok(at_response!(SIZE, at_response; "(0-100)"))
54    }
55
56    fn set(&mut self, at_response: &'static str, args: Args) -> AtResult<'_, SIZE> {
57        let val_str = args.get(0).ok_or((at_response, AtError::InvalidArgs))?;
58        self.value = val_str.parse().map_err(|_| (at_response, AtError::InvalidArgs))?;
59        Ok(at_response!(SIZE, at_response; "OK"))
60    }
61}
62
63#[unsafe(no_mangle)]
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}
92