From 41212a7a15198e53d205252a02069a7dd6ddadeb Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Sun, 25 Oct 2026 09:08:01 +0100 Subject: initial commit --- src/bots/fdroid/index.rs | 97 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 src/bots/fdroid/index.rs (limited to 'src/bots/fdroid/index.rs') 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, +} + +#[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, +} + +#[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>, +} + +/// 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(deserializer: D) -> Result + 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, + /// Short app descriptions keyed by locale. + #[serde(default)] + pub(super) summary: HashMap, + /// Screenshots keyed first by device type and then by locale. + #[serde(default)] + pub(super) screenshots: HashMap>>, +} + +#[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, +} -- cgit v1.3.1