assorted_debian_utils/
architectures.rs

1// Copyright 2021-2024 Sebastian Ramacher
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
4//! # Helpers to handle Debian architectures
5//!
6//! This module provides helpers for working with Debian architectures as they
7//! appear in various files related to Debian binary and source packages,
8//! archive indices, etc.
9
10use std::{
11    fmt::{Display, Formatter},
12    str::FromStr,
13};
14
15use serde::{Deserialize, Serialize, de::Deserializer};
16
17pub use crate::ParseError;
18use crate::utils::WhitespaceListVisitor;
19
20/// Debian architectures
21///
22/// This enum describes architectures that are release architectures or available on Debian ports.
23/// It also provides `All` as special case for binary independent packages.
24#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Hash, Eq)]
25#[serde(rename_all = "lowercase")]
26pub enum Architecture {
27    /// The `all` architecture for architecture independent packages
28    All,
29    /// The `alpha` architecture
30    Alpha,
31    /// The `amd64` architecture
32    Amd64,
33    /// The `arm64` architecture
34    Arm64,
35    /// The `armel` architecture
36    Armel,
37    /// The `armhf` architecture
38    Armhf,
39    /// The `hppa` architecture
40    Hppa,
41    /// The `hurd-amd64` architecture
42    #[serde(rename = "hurd-amd64")]
43    HurdAmd64,
44    /// The `hurd-i386` architecture
45    #[serde(rename = "hurd-i386")]
46    HurdI386,
47    /// The `i386` architecture
48    I386,
49    /// The `ia64` architecture
50    Ia64,
51    /// The `loong64` architecture
52    Loong64,
53    /// The `m68k` architecture
54    M68k,
55    /// The `mips64el` architecture
56    Mips64el,
57    /// The `mipsel` architecture
58    Mipsel,
59    /// The `powerpc` architecture
60    PowerPC,
61    /// The `ppc64` architecture
62    Ppc64,
63    /// The `ppc64el` architecture
64    Ppc64el,
65    /// The `riscv64` architecture
66    Riscv64,
67    /// The `s390x` architecture
68    S390x,
69    /// The `sh4` architecture
70    Sh4,
71    /// The `sparc64` architecture
72    Sparc64,
73    /// The `x32` architecture
74    X32,
75    /// The `source` architecture
76    Source,
77}
78
79impl Display for Architecture {
80    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
81        write!(f, "{}", self.as_ref())
82    }
83}
84
85impl AsRef<str> for Architecture {
86    fn as_ref(&self) -> &str {
87        match self {
88            Self::All => "all",
89            Self::Alpha => "alpha",
90            Self::Amd64 => "amd64",
91            Self::Arm64 => "arm64",
92            Self::Armel => "armel",
93            Self::Armhf => "armhf",
94            Self::Hppa => "hppa",
95            Self::HurdAmd64 => "hurd-amd64",
96            Self::HurdI386 => "hurd-i386",
97            Self::I386 => "i386",
98            Self::Ia64 => "ia64",
99            Self::Loong64 => "loong64",
100            Self::M68k => "m68k",
101            Self::Mips64el => "mips64el",
102            Self::Mipsel => "mipsel",
103            Self::PowerPC => "powerpc",
104            Self::Ppc64 => "ppc64",
105            Self::Ppc64el => "ppc64el",
106            Self::Riscv64 => "riscv64",
107            Self::S390x => "s390x",
108            Self::Sh4 => "sh4",
109            Self::Sparc64 => "sparc64",
110            Self::X32 => "x32",
111            Self::Source => "source",
112        }
113    }
114}
115
116impl TryFrom<&str> for Architecture {
117    type Error = ParseError;
118
119    fn try_from(value: &str) -> Result<Self, Self::Error> {
120        match value {
121            "all" => Ok(Self::All),
122            "alpha" => Ok(Self::Alpha),
123            "amd64" => Ok(Self::Amd64),
124            "arm64" => Ok(Self::Arm64),
125            "armel" => Ok(Self::Armel),
126            "armhf" => Ok(Self::Armhf),
127            "hppa" => Ok(Self::Hppa),
128            "hurd-amd64" => Ok(Self::HurdAmd64),
129            "hurd-i386" => Ok(Self::HurdI386),
130            "i386" => Ok(Self::I386),
131            "ia64" => Ok(Self::Ia64),
132            "loong64" => Ok(Self::Loong64),
133            "m68k" => Ok(Self::M68k),
134            "mips64el" => Ok(Self::Mips64el),
135            "mipsel" => Ok(Self::Mipsel),
136            "powerpc" => Ok(Self::PowerPC),
137            "ppc64" => Ok(Self::Ppc64),
138            "ppc64el" => Ok(Self::Ppc64el),
139            "riscv64" => Ok(Self::Riscv64),
140            "s390x" => Ok(Self::S390x),
141            "sh4" => Ok(Self::Sh4),
142            "sparc64" => Ok(Self::Sparc64),
143            "x32" => Ok(Self::X32),
144            "source" => Ok(Self::Source),
145            _ => Err(ParseError::InvalidArchitecture),
146        }
147    }
148}
149
150impl FromStr for Architecture {
151    type Err = ParseError;
152
153    fn from_str(s: &str) -> Result<Self, Self::Err> {
154        Self::try_from(s)
155    }
156}
157
158/// Deserialize a list of architectures into a `Vec<Architecture>`
159pub(crate) fn deserialize_architectures<'de, D>(
160    deserializer: D,
161) -> Result<Vec<Architecture>, D::Error>
162where
163    D: Deserializer<'de>,
164{
165    deserializer.deserialize_str(WhitespaceListVisitor::new("Architecture"))
166}
167
168#[cfg(test)]
169mod test {
170    use super::Architecture;
171
172    #[test]
173    fn from_str() {
174        assert_eq!(
175            Architecture::try_from("amd64").unwrap(),
176            Architecture::Amd64
177        );
178    }
179}