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 `arc` architecture
34    Arc,
35    /// The `arm64` architecture
36    Arm64,
37    /// The `armel` architecture
38    Armel,
39    /// The `armhf` architecture
40    Armhf,
41    /// The `hppa` architecture
42    Hppa,
43    /// The `hurd-amd64` architecture
44    #[serde(rename = "hurd-amd64")]
45    HurdAmd64,
46    /// The `hurd-i386` architecture
47    #[serde(rename = "hurd-i386")]
48    HurdI386,
49    /// The `i386` architecture
50    I386,
51    /// The `ia64` architecture
52    Ia64,
53    /// The `loong64` architecture
54    Loong64,
55    /// The `m68k` architecture
56    M68k,
57    /// The `mips64el` architecture
58    Mips64el,
59    /// The `mipsel` architecture
60    Mipsel,
61    /// The `powerpc` architecture
62    PowerPC,
63    /// The `ppc64` architecture
64    Ppc64,
65    /// The `ppc64el` architecture
66    Ppc64el,
67    /// The `riscv64` architecture
68    Riscv64,
69    /// The `s390x` architecture
70    S390x,
71    /// The `sh4` architecture
72    Sh4,
73    /// The `sparc64` architecture
74    Sparc64,
75    /// The `x32` architecture
76    X32,
77    /// The `source` architecture
78    Source,
79}
80
81impl Display for Architecture {
82    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
83        write!(f, "{}", self.as_ref())
84    }
85}
86
87impl AsRef<str> for Architecture {
88    fn as_ref(&self) -> &str {
89        match self {
90            Self::All => "all",
91            Self::Alpha => "alpha",
92            Self::Amd64 => "amd64",
93            Self::Arc => "arc",
94            Self::Arm64 => "arm64",
95            Self::Armel => "armel",
96            Self::Armhf => "armhf",
97            Self::Hppa => "hppa",
98            Self::HurdAmd64 => "hurd-amd64",
99            Self::HurdI386 => "hurd-i386",
100            Self::I386 => "i386",
101            Self::Ia64 => "ia64",
102            Self::Loong64 => "loong64",
103            Self::M68k => "m68k",
104            Self::Mips64el => "mips64el",
105            Self::Mipsel => "mipsel",
106            Self::PowerPC => "powerpc",
107            Self::Ppc64 => "ppc64",
108            Self::Ppc64el => "ppc64el",
109            Self::Riscv64 => "riscv64",
110            Self::S390x => "s390x",
111            Self::Sh4 => "sh4",
112            Self::Sparc64 => "sparc64",
113            Self::X32 => "x32",
114            Self::Source => "source",
115        }
116    }
117}
118
119impl TryFrom<&str> for Architecture {
120    type Error = ParseError;
121
122    fn try_from(value: &str) -> Result<Self, Self::Error> {
123        match value {
124            "all" => Ok(Self::All),
125            "alpha" => Ok(Self::Alpha),
126            "amd64" => Ok(Self::Amd64),
127            "arc" => Ok(Self::Arc),
128            "arm64" => Ok(Self::Arm64),
129            "armel" => Ok(Self::Armel),
130            "armhf" => Ok(Self::Armhf),
131            "hppa" => Ok(Self::Hppa),
132            "hurd-amd64" => Ok(Self::HurdAmd64),
133            "hurd-i386" => Ok(Self::HurdI386),
134            "i386" => Ok(Self::I386),
135            "ia64" => Ok(Self::Ia64),
136            "loong64" => Ok(Self::Loong64),
137            "m68k" => Ok(Self::M68k),
138            "mips64el" => Ok(Self::Mips64el),
139            "mipsel" => Ok(Self::Mipsel),
140            "powerpc" => Ok(Self::PowerPC),
141            "ppc64" => Ok(Self::Ppc64),
142            "ppc64el" => Ok(Self::Ppc64el),
143            "riscv64" => Ok(Self::Riscv64),
144            "s390x" => Ok(Self::S390x),
145            "sh4" => Ok(Self::Sh4),
146            "sparc64" => Ok(Self::Sparc64),
147            "x32" => Ok(Self::X32),
148            "source" => Ok(Self::Source),
149            _ => Err(ParseError::InvalidArchitecture),
150        }
151    }
152}
153
154impl FromStr for Architecture {
155    type Err = ParseError;
156
157    fn from_str(s: &str) -> Result<Self, Self::Err> {
158        Self::try_from(s)
159    }
160}
161
162/// Deserialize a list of architectures into a `Vec<Architecture>`
163pub(crate) fn deserialize_architectures<'de, D>(
164    deserializer: D,
165) -> Result<Vec<Architecture>, D::Error>
166where
167    D: Deserializer<'de>,
168{
169    deserializer.deserialize_str(WhitespaceListVisitor::new("Architecture"))
170}
171
172#[cfg(test)]
173mod test {
174    use super::Architecture;
175
176    #[test]
177    fn from_str() {
178        assert_eq!(
179            Architecture::try_from("amd64").unwrap(),
180            Architecture::Amd64
181        );
182    }
183}