1use crate::Arguments;
2use core::fmt::Formatter;
3
4#[derive(Debug)]
5pub enum ArgumentError {
6 ArgOutOfRangeUnsigned { index: usize, value: u32, start: u32, end: u32 },
7 ArgOutOfRangeSigned { index: usize, value: i32, start: i32, end: i32 },
8 ArgCount { value: usize, expected: usize },
9 UnknownMnemonic,
10}
11
12impl core::fmt::Display for ArgumentError {
13 fn fmt(&self, _f: &mut Formatter<'_>) -> core::fmt::Result {
14 todo!()
15 }
16}
17
18#[cfg(feature = "std")]
19impl std::error::Error for ArgumentError {}
20
21#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
22pub enum Argument {
23 #[default]
24 None,
25 Unsigned(u32),
26 Signed(i32),
27}
28
29pub const fn parse_unsigned(
30 args: &Arguments,
31 index: usize,
32 start: u32,
33 end: u32,
34) -> Result<u32, ArgumentError> {
35 match args[index] {
36 Argument::Unsigned(value) => {
37 if value >= start && value <= end {
38 Ok(value)
39 } else {
40 Err(ArgumentError::ArgOutOfRangeUnsigned { index, value, start, end })
41 }
42 }
43 Argument::Signed(value) => {
44 if value >= start as i32 && value <= end as i32 {
45 Ok(value as u32)
46 } else {
47 Err(ArgumentError::ArgOutOfRangeUnsigned { index, value: value as u32, start, end })
48 }
49 }
50 Argument::None => Err(ArgumentError::ArgCount { value: index, expected: index + 1 }),
51 }
52}
53
54pub const fn parse_signed(
55 args: &Arguments,
56 index: usize,
57 start: i32,
58 end: i32,
59) -> Result<i32, ArgumentError> {
60 match args[index] {
61 Argument::Unsigned(value) => {
62 if (start < 0 || value >= start as u32) && value <= end as u32 {
63 Ok(value as i32)
64 } else {
65 Err(ArgumentError::ArgOutOfRangeSigned { index, value: value as i32, start, end })
66 }
67 }
68 Argument::Signed(value) => {
69 if value >= start && value <= end {
70 Ok(value)
71 } else {
72 Err(ArgumentError::ArgOutOfRangeSigned { index, value, start, end })
73 }
74 }
75 Argument::None => Err(ArgumentError::ArgCount { value: index, expected: index + 1 }),
76 }
77}
78
79pub const fn arg_count(args: &Arguments) -> usize {
80 let mut i = 0;
81 while i < args.len() && !matches!(args[i], Argument::None) {
82 i += 1;
83 }
84 i
85}
86
87pub const fn check_arg_count(args: &Arguments, expected: usize) -> Result<(), ArgumentError> {
88 let value = arg_count(args);
89 if value == expected {
90 Ok(())
91 } else {
92 Err(ArgumentError::ArgCount { value, expected })
93 }
94}