Skip to main content

apk/types/
abi.rs

1use std::fmt;
2use std::str::FromStr;
3
4/// An Android application binary interface, which selects the `lib/<abi>/`
5/// directory a native library is stored in.
6#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
7pub enum Abi {
8    ArmeabiV7a,
9    Arm64V8a,
10    X86,
11    X86_64,
12    Riscv64,
13}
14
15/// An ABI name that Android does not define.
16#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
17#[error("unknown Android ABI {name:?}")]
18pub struct UnknownAbi {
19    pub name: String,
20}
21
22impl Abi {
23    pub const ALL: [Abi; 5] = [Self::ArmeabiV7a, Self::Arm64V8a, Self::X86, Self::X86_64, Self::Riscv64];
24
25    /// The directory name under `lib/`, e.g. `arm64-v8a`.
26    pub const fn as_str(self) -> &'static str {
27        match self {
28            Self::ArmeabiV7a => "armeabi-v7a",
29            Self::Arm64V8a => "arm64-v8a",
30            Self::X86 => "x86",
31            Self::X86_64 => "x86_64",
32            Self::Riscv64 => "riscv64",
33        }
34    }
35
36    pub const fn is_64_bit(self) -> bool {
37        matches!(self, Self::Arm64V8a | Self::X86_64 | Self::Riscv64)
38    }
39
40    /// The Rust target triple conventionally used to build for this ABI.
41    pub const fn rust_target(self) -> &'static str {
42        match self {
43            Self::ArmeabiV7a => "armv7-linux-androideabi",
44            Self::Arm64V8a => "aarch64-linux-android",
45            Self::X86 => "i686-linux-android",
46            Self::X86_64 => "x86_64-linux-android",
47            Self::Riscv64 => "riscv64-linux-android",
48        }
49    }
50}
51
52impl fmt::Display for Abi {
53    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54        f.write_str(self.as_str())
55    }
56}
57
58impl FromStr for Abi {
59    type Err = UnknownAbi;
60    fn from_str(name: &str) -> Result<Self, UnknownAbi> {
61        Self::ALL.into_iter().find(|abi| abi.as_str() == name).ok_or_else(|| UnknownAbi { name: name.to_owned() })
62    }
63}