getargs_derive/
value_enum.rs1pub trait ValueEnum: Sized + 'static {
7 const VARIANTS: &'static [Self];
9
10 const POSSIBLE_VALUES: &'static [&'static str];
13
14 #[doc(hidden)]
15 const __VARIANT_IDENTS: &'static [&'static str] = &[];
16
17 fn value_name(&self) -> &'static str;
19
20 fn from_value(value: &str) -> Option<Self>;
22}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
27pub struct ParseValueEnumError;
28
29impl core::fmt::Display for ParseValueEnumError {
30 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
31 f.write_str("the value matches none of the possible values")
32 }
33}
34
35impl core::error::Error for ParseValueEnumError {}
36
37#[doc(hidden)]
38pub enum HelpPart {
39 Text(&'static str),
40 List(&'static [&'static str]),
41}
42
43const SEPARATOR: &str = ", ";
44
45#[doc(hidden)]
46pub const fn help_len(parts: &[HelpPart]) -> usize {
47 let mut length = 0;
48 let mut index = 0;
49 while index < parts.len() {
50 match parts[index] {
51 HelpPart::Text(text) => length += text.len(),
52 HelpPart::List(values) => {
53 let mut value = 0;
54 while value < values.len() {
55 if value > 0 {
56 length += SEPARATOR.len();
57 }
58 length += values[value].len();
59 value += 1;
60 }
61 }
62 }
63 index += 1;
64 }
65 length
66}
67
68const fn copy(bytes: &mut [u8], mut position: usize, text: &str) -> usize {
69 let text = text.as_bytes();
70 let mut index = 0;
71 while index < text.len() {
72 bytes[position] = text[index];
73 position += 1;
74 index += 1;
75 }
76 position
77}
78
79#[doc(hidden)]
80pub const fn help_bytes<const N: usize>(parts: &[HelpPart]) -> [u8; N] {
81 let mut bytes = [0; N];
82 let mut position = 0;
83 let mut index = 0;
84 while index < parts.len() {
85 match parts[index] {
86 HelpPart::Text(text) => position = copy(&mut bytes, position, text),
87 HelpPart::List(values) => {
88 let mut value = 0;
89 while value < values.len() {
90 if value > 0 {
91 position = copy(&mut bytes, position, SEPARATOR);
92 }
93 position = copy(&mut bytes, position, values[value]);
94 value += 1;
95 }
96 }
97 }
98 index += 1;
99 }
100 bytes
101}
102
103#[doc(hidden)]
104pub const fn help_str(bytes: &'static [u8]) -> &'static str {
105 match core::str::from_utf8(bytes) {
106 Ok(text) => text,
107 Err(_) => panic!("generated help is not valid UTF-8"),
108 }
109}
110
111const fn str_eq(left: &str, right: &str) -> bool {
112 let left = left.as_bytes();
113 let right = right.as_bytes();
114 if left.len() != right.len() {
115 return false;
116 }
117 let mut index = 0;
118 while index < left.len() {
119 if left[index] != right[index] {
120 return false;
121 }
122 index += 1;
123 }
124 true
125}
126
127#[doc(hidden)]
128pub const fn value_name(
129 idents: &[&str],
130 values: &'static [&'static str],
131 ident: &str,
132 fallback: &'static str,
133) -> &'static str {
134 let mut index = 0;
135 while index < idents.len() && index < values.len() {
136 if str_eq(idents[index], ident) {
137 return values[index];
138 }
139 index += 1;
140 }
141 fallback
142}