1use std::str::FromStr;
2
3use alpm_parsers::iter_str_context;
4use serde::{Deserialize, Serialize};
5use strum::{Display, EnumString, VariantNames};
6use winnow::{ModalResult, Parser, combinator::cut_err, error::StrContext, token::rest};
7
8#[derive(
39 Clone,
40 Copy,
41 Debug,
42 Deserialize,
43 Display,
44 EnumString,
45 Eq,
46 Hash,
47 Ord,
48 PartialEq,
49 PartialOrd,
50 Serialize,
51 VariantNames,
52)]
53#[strum(serialize_all = "lowercase")]
54#[serde(rename_all = "lowercase")]
55pub enum Architecture {
56 Aarch64,
58 Any,
60 Arm,
62 Armv6h,
64 Armv7h,
66 I386,
68 I486,
70 I686,
72 Pentium4,
74 Riscv32,
76 Riscv64,
78 X86_64,
80 #[strum(to_string = "x86_64_v2")]
82 X86_64V2,
83 #[strum(to_string = "x86_64_v3")]
85 X86_64V3,
86 #[strum(to_string = "x86_64_v4")]
88 X86_64V4,
89}
90
91impl Architecture {
92 pub fn parser(input: &mut &str) -> ModalResult<Architecture> {
96 cut_err(rest.try_map(Architecture::from_str))
97 .context(StrContext::Label("architecture"))
98 .context_with(iter_str_context!([Architecture::VARIANTS]))
99 .parse_next(input)
100 }
101}
102
103#[derive(
134 Clone, Copy, Debug, Deserialize, Display, EnumString, Eq, Ord, PartialEq, PartialOrd, Serialize,
135)]
136#[strum(serialize_all = "lowercase")]
137pub enum ElfArchitectureFormat {
138 #[strum(to_string = "32")]
140 Bit32 = 32,
141 #[strum(to_string = "64")]
143 Bit64 = 64,
144}
145
146#[cfg(test)]
147mod tests {
148 use std::str::FromStr;
149
150 use rstest::rstest;
151 use strum::ParseError;
152 use winnow::error::ContextError;
153
154 use super::*;
155
156 #[rstest]
157 #[case("aarch64", Ok(Architecture::Aarch64))]
158 #[case("any", Ok(Architecture::Any))]
159 #[case("arm", Ok(Architecture::Arm))]
160 #[case("armv6h", Ok(Architecture::Armv6h))]
161 #[case("armv7h", Ok(Architecture::Armv7h))]
162 #[case("i386", Ok(Architecture::I386))]
163 #[case("i486", Ok(Architecture::I486))]
164 #[case("i686", Ok(Architecture::I686))]
165 #[case("pentium4", Ok(Architecture::Pentium4))]
166 #[case("riscv32", Ok(Architecture::Riscv32))]
167 #[case("riscv64", Ok(Architecture::Riscv64))]
168 #[case("x86_64", Ok(Architecture::X86_64))]
169 #[case("x86_64_v2", Ok(Architecture::X86_64V2))]
170 #[case("x86_64_v3", Ok(Architecture::X86_64V3))]
171 #[case("x86_64_v4", Ok(Architecture::X86_64V4))]
172 #[case("foo", Err(ParseError::VariantNotFound))]
173 fn architecture_from_string(#[case] s: &str, #[case] arch: Result<Architecture, ParseError>) {
174 assert_eq!(Architecture::from_str(s), arch);
175 }
176
177 #[rstest]
178 #[case("aarch64", Ok(Architecture::Aarch64))]
179 #[case("any", Ok(Architecture::Any))]
180 #[case("arm", Ok(Architecture::Arm))]
181 #[case("armv6h", Ok(Architecture::Armv6h))]
182 #[case("armv7h", Ok(Architecture::Armv7h))]
183 #[case("i386", Ok(Architecture::I386))]
184 #[case("i486", Ok(Architecture::I486))]
185 #[case("i686", Ok(Architecture::I686))]
186 #[case("pentium4", Ok(Architecture::Pentium4))]
187 #[case("riscv32", Ok(Architecture::Riscv32))]
188 #[case("riscv64", Ok(Architecture::Riscv64))]
189 #[case("x86_64", Ok(Architecture::X86_64))]
190 #[case("x86_64_v2", Ok(Architecture::X86_64V2))]
191 #[case("x86_64_v3", Ok(Architecture::X86_64V3))]
192 #[case("x86_64_v4", Ok(Architecture::X86_64V4))]
193 fn architecture_parser(
194 #[case] s: &str,
195 #[case] arch: Result<Architecture, winnow::error::ParseError<&str, ContextError>>,
196 ) {
197 assert_eq!(Architecture::parser.parse(s), arch);
198 }
199
200 #[rstest]
201 #[case(Architecture::Aarch64, "aarch64")]
202 #[case(Architecture::Any, "any")]
203 #[case(Architecture::Arm, "arm")]
204 #[case(Architecture::Armv6h, "armv6h")]
205 #[case(Architecture::Armv7h, "armv7h")]
206 #[case(Architecture::I386, "i386")]
207 #[case(Architecture::I486, "i486")]
208 #[case(Architecture::I686, "i686")]
209 #[case(Architecture::Pentium4, "pentium4")]
210 #[case(Architecture::Riscv32, "riscv32")]
211 #[case(Architecture::Riscv64, "riscv64")]
212 #[case(Architecture::X86_64, "x86_64")]
213 #[case(Architecture::X86_64V2, "x86_64_v2")]
214 #[case(Architecture::X86_64V3, "x86_64_v3")]
215 #[case(Architecture::X86_64V4, "x86_64_v4")]
216 fn architecture_format_string(#[case] arch: Architecture, #[case] arch_str: &str) {
217 assert_eq!(arch_str, format!("{arch}"));
218 }
219
220 #[rstest]
221 #[case("32", Ok(ElfArchitectureFormat::Bit32))]
222 #[case("64", Ok(ElfArchitectureFormat::Bit64))]
223 #[case("foo", Err(ParseError::VariantNotFound))]
224 fn elf_architecture_format_from_string(
225 #[case] s: &str,
226 #[case] arch: Result<ElfArchitectureFormat, ParseError>,
227 ) {
228 assert_eq!(ElfArchitectureFormat::from_str(s), arch);
229 }
230
231 #[rstest]
232 #[case(ElfArchitectureFormat::Bit32, "32")]
233 #[case(ElfArchitectureFormat::Bit64, "64")]
234 fn elf_architecture_format_display(
235 #[case] arch: ElfArchitectureFormat,
236 #[case] arch_str: &str,
237 ) {
238 assert_eq!(arch_str, format!("{arch}"));
239 }
240}