rust-apk 1.0.0

Build, align, sign, verify, and inspect Android APKs in pure Rust
Documentation
use std::fmt;
use std::str::FromStr;

/// An Android application binary interface, which selects the `lib/<abi>/`
/// directory a native library is stored in.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Abi {
    ArmeabiV7a,
    Arm64V8a,
    X86,
    X86_64,
    Riscv64,
}

/// An ABI name that Android does not define.
#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
#[error("unknown Android ABI {name:?}")]
pub struct UnknownAbi {
    pub name: String,
}

impl Abi {
    pub const ALL: [Abi; 5] = [Self::ArmeabiV7a, Self::Arm64V8a, Self::X86, Self::X86_64, Self::Riscv64];

    /// The directory name under `lib/`, e.g. `arm64-v8a`.
    pub const fn as_str(self) -> &'static str {
        match self {
            Self::ArmeabiV7a => "armeabi-v7a",
            Self::Arm64V8a => "arm64-v8a",
            Self::X86 => "x86",
            Self::X86_64 => "x86_64",
            Self::Riscv64 => "riscv64",
        }
    }

    pub const fn is_64_bit(self) -> bool {
        matches!(self, Self::Arm64V8a | Self::X86_64 | Self::Riscv64)
    }

    /// The Rust target triple conventionally used to build for this ABI.
    pub const fn rust_target(self) -> &'static str {
        match self {
            Self::ArmeabiV7a => "armv7-linux-androideabi",
            Self::Arm64V8a => "aarch64-linux-android",
            Self::X86 => "i686-linux-android",
            Self::X86_64 => "x86_64-linux-android",
            Self::Riscv64 => "riscv64-linux-android",
        }
    }
}

impl fmt::Display for Abi {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(self.as_str())
    }
}

impl FromStr for Abi {
    type Err = UnknownAbi;
    fn from_str(name: &str) -> Result<Self, UnknownAbi> {
        Self::ALL.into_iter().find(|abi| abi.as_str() == name).ok_or_else(|| UnknownAbi { name: name.to_owned() })
    }
}