diff options
| author | Martin Fischer <martin@push-f.com> | 2026-10-25 09:08:01 +0100 |
|---|---|---|
| committer | Martin Fischer <martin@push-f.com> | 2026-10-25 19:10:47 +0100 |
| commit | 41212a7a15198e53d205252a02069a7dd6ddadeb (patch) | |
| tree | 38a24eebf956b2453675ac1cefec925faf09de02 /src/bots/fdroid/index.rs | |
initial commit
Diffstat (limited to 'src/bots/fdroid/index.rs')
| -rw-r--r-- | src/bots/fdroid/index.rs | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/bots/fdroid/index.rs b/src/bots/fdroid/index.rs new file mode 100644 index 0000000..61cc44d --- /dev/null +++ b/src/bots/fdroid/index.rs @@ -0,0 +1,97 @@ +//! Types for the F-Droid repository index. + +use std::collections::HashMap; + +use serde::{Deserialize, Deserializer}; + +pub(super) const PHONE_DEVICE_TYPE: &str = "phone"; +pub(super) const EN_LOCALE: &str = "en-US"; + +#[derive(Debug, Deserialize)] +pub(super) struct Index { + pub(super) repo: Repo, + pub(super) packages: HashMap<String, Package>, +} + +#[derive(Debug, Deserialize)] +pub(super) struct Repo { + pub(super) timestamp: u64, +} + +#[derive(Debug, Deserialize)] +pub(super) struct Package { + pub(super) metadata: Metadata, + /// Releases keyed by the APK's SHA-256 digest. + pub(super) versions: HashMap<String, Version>, +} + +#[derive(Debug, Deserialize)] +pub(super) struct Version { + /// Anti-feature explanations keyed first by anti-feature name and then by locale. + #[serde(default, rename = "antiFeatures")] + pub(super) anti_features: HashMap<AntiFeature, HashMap<String, String>>, +} + +/// An [anti-feature](https://f-droid.org/docs/Anti-Features/). +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub(super) enum AntiFeature { + Ads, + DisabledAlgorithm, + KnownVuln, + NoSourceSince, + NonFreeAdd, + NonFreeAssets, + NonFreeDep, + NonFreeNet, + TetheredNet, + Tracking, + Other(String), +} + +impl<'de> Deserialize<'de> for AntiFeature { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + let name = String::deserialize(deserializer)?; + Ok(match name.as_str() { + "Ads" => Self::Ads, + "DisabledAlgorithm" => Self::DisabledAlgorithm, + "KnownVuln" => Self::KnownVuln, + "NoSourceSince" => Self::NoSourceSince, + "NonFreeAdd" => Self::NonFreeAdd, + "NonFreeAssets" => Self::NonFreeAssets, + "NonFreeDep" => Self::NonFreeDep, + "NonFreeNet" => Self::NonFreeNet, + "TetheredNet" => Self::TetheredNet, + "Tracking" => Self::Tracking, + _ => { + tracing::warn!("observed unknown F-Droid anti-feature {name}"); + Self::Other(name) + } + }) + } +} + +#[derive(Debug, Deserialize)] +pub(super) struct Metadata { + pub(super) added: u64, + /// App names keyed by locale. Every package has an `en-US` name. + #[serde(default)] + pub(super) name: HashMap<String, String>, + /// Short app descriptions keyed by locale. + #[serde(default)] + pub(super) summary: HashMap<String, String>, + /// Screenshots keyed first by device type and then by locale. + #[serde(default)] + pub(super) screenshots: HashMap<String, HashMap<String, Vec<Screenshot>>>, +} + +#[derive(Debug, Deserialize)] +pub(super) struct Screenshot { + /// Path to the screenshot relative to the repository address. + pub(super) name: String, + /// Screenshot file size in bytes, retained for enforcing upload limits. + #[allow(dead_code)] + pub(super) size: u64, +} |
