// Copyright (c) [2025-2026] SUSE LLC // // All Rights Reserved. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, contact SUSE LLC. // // To contact SUSE LLC about this file by physical or electronic mail, you may // find current contact information at www.suse.com. //! Implement support for detecting and converting architeture identifiers. #[derive(Clone, Copy, Debug, PartialEq, strum::Display, strum::EnumString)] #[strum(serialize_all = "lowercase")] pub enum Arch { AARCH64, PPC64LE, S390X, X86_64, } #[derive(thiserror::Error, Debug)] pub enum Error { #[error("Unknown architecture: {0}")] Unknown(String), #[error("Could not detect the architecture")] Detect(#[from] std::io::Error), } impl Arch { /// Returns the current architecture. pub fn current() -> Result { match std::env::consts::ARCH { "aarch64" => Ok(Arch::AARCH64), "powerpc64" => Ok(Arch::PPC64LE), "s390x" => Ok(Arch::S390X), "x86_64" => Ok(Arch::X86_64), _ => Err(Error::Unknown(std::env::consts::ARCH.to_string())), } } /// Returns the identifier used in the products definition. pub fn to_yast_id(&self) -> String { match &self { Arch::AARCH64 => "aarch64".to_string(), Arch::PPC64LE => "ppc".to_string(), Arch::S390X => "s390".to_string(), Arch::X86_64 => "x86_64".to_string(), } } /// Whether the current architecture is s390. pub fn is_s390() -> bool { let Ok(arch) = Self::current() else { tracing::error!("Failed to determine the architecture"); return false; }; arch == Self::S390X } } #[cfg(test)] mod tests { use super::*; #[test] fn test_arch_from_string() { assert_eq!("aarch64".try_into(), Ok(Arch::AARCH64)); assert_eq!("ppc64le".try_into(), Ok(Arch::PPC64LE)); assert_eq!("s390x".try_into(), Ok(Arch::S390X)); assert_eq!("x86_64".try_into(), Ok(Arch::X86_64)); } #[test] fn test_arch_to_string() { assert_eq!(Arch::AARCH64.to_string(), "aarch64".to_string()); assert_eq!(Arch::PPC64LE.to_string(), "ppc64le".to_string()); assert_eq!(Arch::S390X.to_string(), "s390x".to_string()); assert_eq!(Arch::X86_64.to_string(), "x86_64".to_string()); } #[test] fn test_to_product_string() { assert_eq!(Arch::AARCH64.to_yast_id(), "aarch64".to_string()); assert_eq!(Arch::PPC64LE.to_yast_id(), "ppc".to_string()); assert_eq!(Arch::S390X.to_yast_id(), "s390".to_string()); assert_eq!(Arch::X86_64.to_yast_id(), "x86_64".to_string()); } #[cfg(target_arch = "aarch64")] #[test] fn test_current_arch_aarch64() { assert_eq!(Arch::current().unwrap(), Arch::AARCH64); } #[cfg(target_arch = "powerpc64")] #[test] fn test_current_arch_powerpc64() { assert_eq!(Arch::current().unwrap(), Arch::PPC64LE); } #[cfg(target_arch = "s390x")] #[test] fn test_current_arch_s390x() { assert_eq!(Arch::current().unwrap(), Arch::S390X); } #[cfg(target_arch = "x86_64")] #[test] fn test_current_arch_x86_64() { assert_eq!(Arch::current().unwrap(), Arch::X86_64); } #[cfg(target_arch = "s390x")] #[test] fn test_arch_is_s390() { assert!(Arch::is_s390()); } #[cfg(not(target_arch = "s390x"))] #[test] fn test_arch_is_not_s390() { assert!(!Arch::is_s390()); } }