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, Bytes};
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(&self) -> AtResult<SIZE> {
45        Ok(Bytes::from_str("Test command executed"))
46    }
47
48    fn query(&mut self) -> AtResult<SIZE> {
49        if self.value == 0 {
50            Ok(Bytes::from_str("0"))
51        } else if self.value < 10 {
52            Ok(Bytes::from_str("1-9"))
53        } else {
54            Ok(Bytes::from_str("10+"))
55        }
56    }
57
58    fn test(&mut self) -> AtResult<SIZE> {
59        Ok(Bytes::from_str("Test: 0-100"))
60    }
61
62    fn set(&mut self, args: Args) -> AtResult<SIZE> {
63        let val_str = args.get(0).ok_or(AtError::InvalidArgs)?;
64        self.value = val_str.parse().map_err(|_| AtError::InvalidArgs)?;
65        Ok(Bytes::from_str("OK"))
66    }
67}
68
69#[unsafe(no_mangle)]
70pub extern "C" fn main() -> ! {
71    let mut cmd1 = TestCommand { value: 0 };
72    let mut cmd2 = TestCommand { value: 5 };
73    let mut cmd3 = TestCommand { value: 10 };
74
75    let mut parser: AtParser<TestCommand, SIZE> = AtParser::new();
76
77    let commands: &mut [(&str, &mut TestCommand)] = &mut [
78        ("AT+CMD1", &mut cmd1),
79        ("AT+CMD2", &mut cmd2),
80        ("AT+CMD3", &mut cmd3),
81    ];
82    parser.set_commands(commands);
83
84    // Execute (no-op result, just exercising the API)
85    let _ = parser.execute("AT+CMD1");
86    let _ = parser.execute("AT+CMD1?");
87    let _ = parser.execute("AT+CMD1=?");
88    let _ = parser.execute("AT+CMD1=42");
89    let _ = parser.execute("AT+CMD1?");
90    let _ = parser.execute("AT+CMD2");
91    let _ = parser.execute("AT+CMD2?");
92    let _ = parser.execute("AT+CMD3=100");
93    let _ = parser.execute("AT+CMD3?");
94    let _ = parser.execute("AT+UNKNOWN");   // -> Err(UnknownCommand)
95    let _ = parser.execute("AT+CMD1=abc");  // -> Err(InvalidArgs)
96
97    loop {}
98}