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